mtk_cooler_atm.c 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796
  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 <linux/types.h>
  7. #include <linux/proc_fs.h>
  8. #include "mt-plat/mtk_thermal_monitor.h"
  9. #include "mtk_thermal_typedefs.h"
  10. #include "mach/mt_thermal.h"
  11. #include "mt-plat/mtk_thermal_platform.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. #include <mt-plat/aee.h>
  19. #include <linux/uidgid.h>
  20. #if defined(CONFIG_ARCH_MT6755)
  21. /* TODO: use PPM's kconfig instead */
  22. #define ATM_USES_PPM (1)
  23. #endif
  24. #ifdef ATM_USES_PPM
  25. #include "mach/mt_ppm_api.h"
  26. #else
  27. #include "mt_cpufreq.h"
  28. #endif
  29. /*=============================================================
  30. *Local variable definition
  31. *=============================================================*/
  32. static int print_cunt;
  33. static int adaptive_limit[5][2];
  34. static kuid_t uid = KUIDT_INIT(0);
  35. static kgid_t gid = KGIDT_INIT(1000);
  36. unsigned int adaptive_cpu_power_limit = 0x7FFFFFFF;
  37. unsigned int adaptive_gpu_power_limit = 0x7FFFFFFF;
  38. static unsigned int prv_adp_cpu_pwr_lim;
  39. unsigned int gv_cpu_power_limit = 0x7FFFFFFF;
  40. unsigned int gv_gpu_power_limit = 0x7FFFFFFF;
  41. #if CPT_ADAPTIVE_AP_COOLER
  42. static int TARGET_TJ = 65000;
  43. static int cpu_target_tj = 65000;
  44. static int cpu_target_offset = 10000;
  45. static int TARGET_TJ_HIGH = 66000;
  46. static int TARGET_TJ_LOW = 64000;
  47. static int PACKAGE_THETA_JA_RISE = 10;
  48. static int PACKAGE_THETA_JA_FALL = 10;
  49. static int MINIMUM_CPU_POWER = 500;
  50. static int MAXIMUM_CPU_POWER = 1240;
  51. static int MINIMUM_GPU_POWER = 676;
  52. static int MAXIMUM_GPU_POWER = 676;
  53. static int MINIMUM_TOTAL_POWER = 500 + 676;
  54. static int MAXIMUM_TOTAL_POWER = 1240 + 676;
  55. static int FIRST_STEP_TOTAL_POWER_BUDGET = 1750;
  56. /* 1. MINIMUM_BUDGET_CHANGE = 0 ==> thermal equilibrium maybe at higher than TARGET_TJ_HIGH */
  57. /* 2. Set MINIMUM_BUDGET_CHANGE > 0 if to keep Tj at TARGET_TJ */
  58. static int MINIMUM_BUDGET_CHANGE = 50;
  59. static int g_total_power;
  60. #endif
  61. #if CPT_ADAPTIVE_AP_COOLER
  62. static struct thermal_cooling_device *cl_dev_adp_cpu[MAX_CPT_ADAPTIVE_COOLERS] = { NULL };
  63. static unsigned int cl_dev_adp_cpu_state[MAX_CPT_ADAPTIVE_COOLERS] = { 0 };
  64. int TARGET_TJS[MAX_CPT_ADAPTIVE_COOLERS] = { 85000, 0 };
  65. static unsigned int cl_dev_adp_cpu_state_active;
  66. #endif /* end of CPT_ADAPTIVE_AP_COOLER */
  67. #if CPT_ADAPTIVE_AP_COOLER
  68. char *adaptive_cooler_name = "cpu_adaptive_";
  69. static int FIRST_STEP_TOTAL_POWER_BUDGETS[MAX_CPT_ADAPTIVE_COOLERS] = { 3300, 0 };
  70. static int PACKAGE_THETA_JA_RISES[MAX_CPT_ADAPTIVE_COOLERS] = { 35, 0 };
  71. static int PACKAGE_THETA_JA_FALLS[MAX_CPT_ADAPTIVE_COOLERS] = { 25, 0 };
  72. static int MINIMUM_BUDGET_CHANGES[MAX_CPT_ADAPTIVE_COOLERS] = { 50, 0 };
  73. static int MINIMUM_CPU_POWERS[MAX_CPT_ADAPTIVE_COOLERS] = { 1200, 0 };
  74. static int MAXIMUM_CPU_POWERS[MAX_CPT_ADAPTIVE_COOLERS] = { 4400, 0 };
  75. static int MINIMUM_GPU_POWERS[MAX_CPT_ADAPTIVE_COOLERS] = { 350, 0 };
  76. static int MAXIMUM_GPU_POWERS[MAX_CPT_ADAPTIVE_COOLERS] = { 960, 0 };
  77. static int active_adp_cooler;
  78. static int GPU_L_H_TRIP = 80, GPU_L_L_TRIP = 40;
  79. /* tscpu_atm
  80. 0: ATMv1 (default)
  81. 1: ATMv2 (FTL)
  82. 2: CPU_GPU_Weight ATM v2
  83. 3: Precise Power Budgeting + Hybrid Power Budgeting
  84. */
  85. static int tscpu_atm = 1;
  86. static int tt_ratio_high_rise = 1;
  87. static int tt_ratio_high_fall = 1;
  88. static int tt_ratio_low_rise = 1;
  89. static int tt_ratio_low_fall = 1;
  90. static int tp_ratio_high_rise = 1;
  91. static int tp_ratio_high_fall;
  92. static int tp_ratio_low_rise;
  93. static int tp_ratio_low_fall;
  94. /* static int cpu_loading = 0; */
  95. static int (*_adaptive_power_calc)(long prev_temp, long curr_temp, unsigned int gpu_loading);
  96. #if PRECISE_HYBRID_POWER_BUDGET
  97. /* initial value: assume 1 degreeC for temp. <=> 1 unit for total_power(0~100) */
  98. struct phpb_param {
  99. int tt, tp;
  100. char type[8];
  101. };
  102. enum {
  103. PHPB_PARAM_CPU = 0,
  104. PHPB_PARAM_GPU,
  105. NR_PHPB_PARAMS
  106. };
  107. static struct phpb_param phpb_params[NR_PHPB_PARAMS];
  108. static const int phpb_theta_min = 1;
  109. static int phpb_theta_max = 4;
  110. static int tj_stable_range = 1000;
  111. static int tj_jump_threshold = 4000;
  112. #if 0
  113. #define MAX_GPU_POWER_SMA_LEN (32)
  114. static unsigned int gpu_power_sma_len = 1;
  115. static unsigned int gpu_power_history[MAX_GPU_POWER_SMA_LEN];
  116. static unsigned int gpu_power_history_idx;
  117. #endif
  118. #endif
  119. #if THERMAL_HEADROOM
  120. static int p_Tpcb_correlation;
  121. static int Tpcb_trip_point;
  122. static int thp_max_cpu_power;
  123. static int thp_p_tj_correlation;
  124. static int thp_threshold_tj;
  125. #endif
  126. #if CONTINUOUS_TM
  127. static int ctm_on = -1; /* 2: cATM+, 1: cATMv1, 0: off */
  128. static int MAX_TARGET_TJ = -1;
  129. static int STEADY_TARGET_TJ = -1;
  130. static int TRIP_TPCB = -1;
  131. static int STEADY_TARGET_TPCB = -1;
  132. static int MAX_EXIT_TJ = -1;
  133. static int STEADY_EXIT_TJ = -1;
  134. static int COEF_AE = -1;
  135. static int COEF_BE = -1;
  136. static int COEF_AX = -1;
  137. static int COEF_BX = -1;
  138. /* static int current_TTJ = -1; */
  139. static int current_ETJ = -1;
  140. /* +++ cATM+ parameters +++ */
  141. /* slope of base_ttj, automatically calculated */
  142. static int K_TT = 4000;
  143. #define MAX_K_SUM_TT (K_TT * 10)
  144. /* for ATM polling delay 50ms, increase this based on polling delay */
  145. static int K_SUM_TT_LOW = 10;
  146. /* for ATM polling delay 50ms, increase this based on polling delay */
  147. static int K_SUM_TT_HIGH = 10;
  148. /* clamp sum_tt (err_integral) between MIN_SUM_TT ~ MAX_SUM_TT, automatically calculated */
  149. static int MIN_SUM_TT = -800000;
  150. static int MAX_SUM_TT = 800000;
  151. static int MIN_TTJ = 65000;
  152. static int CATMP_STEADY_TTJ_DELTA = 10000; /* magic number decided by experience */
  153. /* --- cATM+ parameters --- */
  154. #endif
  155. #endif /* end of CPT_ADAPTIVE_AP_COOLER */
  156. /*=============================================================
  157. *Local function prototype
  158. *=============================================================*/
  159. static void set_adaptive_gpu_power_limit(unsigned int limit);
  160. /*=============================================================
  161. *Weak functions
  162. *=============================================================*/
  163. #ifdef ATM_USES_PPM
  164. void __attribute__ ((weak))
  165. mt_ppm_cpu_thermal_protect(unsigned int limited_power)
  166. {
  167. pr_err("E_WF: %s doesn't exist\n", __func__);
  168. }
  169. #else
  170. void __attribute__ ((weak))
  171. mt_cpufreq_thermal_protect(unsigned int limited_power)
  172. {
  173. pr_err("E_WF: %s doesn't exist\n", __func__);
  174. }
  175. #endif
  176. bool __attribute__((weak))
  177. mtk_get_gpu_loading(unsigned int *pLoading)
  178. {
  179. pr_err("E_WF: %s doesn't exist\n", __func__);
  180. return 0;
  181. }
  182. unsigned int __attribute__((weak))
  183. mt_gpufreq_get_min_power(void)
  184. {
  185. pr_err("E_WF: %s doesn't exist\n", __func__);
  186. return 0;
  187. }
  188. unsigned int __attribute__((weak))
  189. mt_gpufreq_get_max_power(void)
  190. {
  191. pr_err("E_WF: %s doesn't exist\n", __func__);
  192. return 0;
  193. }
  194. /*=============================================================*/
  195. /*
  196. static int step0_mask[11] = {1,1,1,1,1,1,1,1,1,1,1};
  197. static int step1_mask[11] = {0,1,1,1,1,1,1,1,1,1,1};
  198. static int step2_mask[11] = {0,0,1,1,1,1,1,1,1,1,1};
  199. static int step3_mask[11] = {0,0,0,1,1,1,1,1,1,1,1};
  200. static int step4_mask[11] = {0,0,0,0,1,1,1,1,1,1,1};
  201. static int step5_mask[11] = {0,0,0,0,0,1,1,1,1,1,1};
  202. static int step6_mask[11] = {0,0,0,0,0,0,1,1,1,1,1};
  203. static int step7_mask[11] = {0,0,0,0,0,0,0,1,1,1,1};
  204. static int step8_mask[11] = {0,0,0,0,0,0,0,0,1,1,1};
  205. static int step9_mask[11] = {0,0,0,0,0,0,0,0,0,1,1};
  206. static int step10_mask[11]= {0,0,0,0,0,0,0,0,0,0,1};
  207. */
  208. int tsatm_thermal_get_catm_type(void)
  209. {
  210. tscpu_dprintk("tsatm_thermal_get_catm_type ctm_on = %d\n", ctm_on);
  211. return ctm_on;
  212. }
  213. int mtk_thermal_get_tpcb_target(void)
  214. {
  215. return STEADY_TARGET_TPCB;
  216. }
  217. EXPORT_SYMBOL(mtk_thermal_get_tpcb_target);
  218. int get_target_tj(void)
  219. {
  220. return TARGET_TJ;
  221. }
  222. static void set_adaptive_cpu_power_limit(unsigned int limit)
  223. {
  224. unsigned int final_limit;
  225. prv_adp_cpu_pwr_lim = adaptive_cpu_power_limit;
  226. adaptive_cpu_power_limit = (limit != 0) ? limit : 0x7FFFFFFF;
  227. final_limit = MIN(adaptive_cpu_power_limit, static_cpu_power_limit);
  228. if (prv_adp_cpu_pwr_lim != adaptive_cpu_power_limit) {
  229. if (print_cunt < 5) {
  230. adaptive_limit[print_cunt][0] = (final_limit != 0x7FFFFFFF) ? final_limit : 0;
  231. adaptive_limit[print_cunt][1] = tscpu_get_curr_temp();
  232. } else {
  233. tscpu_warn("set_adaptive_cpu_power_limit %d T=%d,%d T=%d,%d T=%d,%d T=%d,%d T=%d\n",
  234. adaptive_limit[0][0] , adaptive_limit[0][1],
  235. adaptive_limit[1][0] , adaptive_limit[1][1],
  236. adaptive_limit[2][0] , adaptive_limit[2][1],
  237. adaptive_limit[3][0] , adaptive_limit[3][1],
  238. adaptive_limit[4][0] , adaptive_limit[4][1]
  239. );
  240. print_cunt = 0;
  241. adaptive_limit[0][0] = (final_limit != 0x7FFFFFFF) ? final_limit : 0;
  242. adaptive_limit[0][1] = tscpu_get_curr_temp();
  243. }
  244. print_cunt++;
  245. #ifdef ATM_USES_PPM
  246. gv_cpu_power_limit = final_limit;
  247. mt_ppm_cpu_thermal_protect((final_limit != 0x7FFFFFFF) ? final_limit : 0);
  248. #else
  249. mt_cpufreq_thermal_protect((final_limit != 0x7FFFFFFF) ? final_limit : 0);
  250. #endif
  251. }
  252. }
  253. static void set_adaptive_gpu_power_limit(unsigned int limit)
  254. {
  255. unsigned int final_limit;
  256. adaptive_gpu_power_limit = (limit != 0) ? limit : 0x7FFFFFFF;
  257. final_limit = MIN(adaptive_gpu_power_limit, static_gpu_power_limit);
  258. tscpu_printk("set_adaptive_gpu_power_limit %d\n",
  259. (final_limit != 0x7FFFFFFF) ? final_limit : 0);
  260. gv_gpu_power_limit = final_limit;
  261. mt_gpufreq_thermal_protect((final_limit != 0x7FFFFFFF) ? final_limit : 0);
  262. }
  263. unsigned int get_adaptive_power_limit(int type)
  264. {
  265. if (type == 0)
  266. return gv_cpu_power_limit;
  267. return gv_gpu_power_limit;
  268. }
  269. #if CPT_ADAPTIVE_AP_COOLER
  270. int is_cpu_power_unlimit(void)
  271. {
  272. return (g_total_power == 0 || g_total_power >= MAXIMUM_TOTAL_POWER) ? 1 : 0;
  273. }
  274. EXPORT_SYMBOL(is_cpu_power_unlimit);
  275. int is_cpu_power_min(void)
  276. {
  277. return (g_total_power <= MINIMUM_TOTAL_POWER) ? 1 : 0;
  278. }
  279. EXPORT_SYMBOL(is_cpu_power_min);
  280. int get_cpu_target_tj(void)
  281. {
  282. return cpu_target_tj;
  283. }
  284. EXPORT_SYMBOL(get_cpu_target_tj);
  285. int get_cpu_target_offset(void)
  286. {
  287. return cpu_target_offset;
  288. }
  289. EXPORT_SYMBOL(get_cpu_target_offset);
  290. /*add for DLPT*/
  291. int tscpu_get_min_cpu_pwr(void)
  292. {
  293. return MINIMUM_CPU_POWER;
  294. }
  295. EXPORT_SYMBOL(tscpu_get_min_cpu_pwr);
  296. int tscpu_get_min_gpu_pwr(void)
  297. {
  298. return MINIMUM_GPU_POWER;
  299. }
  300. EXPORT_SYMBOL(tscpu_get_min_gpu_pwr);
  301. #if CONTINUOUS_TM
  302. /**
  303. * @brief update cATM+ ttj control loop parameters
  304. * everytime related parameters are changed, we need to recalculate.
  305. * from thermal config: MAX_TARGET_TJ, STEADY_TARGET_TJ, MIN_TTJ, TRIP_TPCB...etc
  306. * cATM+'s parameters: K_SUM_TT_HIGH, K_SUM_TT_LOW
  307. */
  308. struct CATM_T thermal_atm_t;
  309. static void catmplus_update_params(void)
  310. {
  311. int ret = 0;
  312. thermal_atm_t.t_catm_par.CATM_ON = ctm_on;
  313. thermal_atm_t.t_catm_par.K_TT = K_TT;
  314. thermal_atm_t.t_catm_par.K_SUM_TT_LOW = K_SUM_TT_LOW;
  315. thermal_atm_t.t_catm_par.K_SUM_TT_HIGH = K_SUM_TT_HIGH;
  316. thermal_atm_t.t_catm_par.MIN_SUM_TT = MIN_SUM_TT;
  317. thermal_atm_t.t_catm_par.MAX_SUM_TT = MAX_SUM_TT;
  318. thermal_atm_t.t_catm_par.MIN_TTJ = MIN_TTJ;
  319. thermal_atm_t.t_catm_par.CATMP_STEADY_TTJ_DELTA = CATMP_STEADY_TTJ_DELTA;
  320. thermal_atm_t.t_continuetm_par.STEADY_TARGET_TJ = STEADY_TARGET_TJ;
  321. thermal_atm_t.t_continuetm_par.MAX_TARGET_TJ = MAX_TARGET_TJ;
  322. thermal_atm_t.t_continuetm_par.TRIP_TPCB = TRIP_TPCB;
  323. thermal_atm_t.t_continuetm_par.STEADY_TARGET_TPCB = STEADY_TARGET_TPCB;
  324. ret = wakeup_ta_algo(TA_CATMPLUS);
  325. /*tscpu_warn("catmplus_update_params : ret %d\n" , ret);*/
  326. }
  327. #endif
  328. #if PRECISE_HYBRID_POWER_BUDGET
  329. static int _get_current_gpu_power(void)
  330. {
  331. unsigned int cur_gpu_freq = mt_gpufreq_get_cur_freq();
  332. unsigned int cur_gpu_power = 0;
  333. int i = 0;
  334. for (; i < Num_of_GPU_OPP; i++)
  335. if (mtk_gpu_power[i].gpufreq_khz == cur_gpu_freq)
  336. cur_gpu_power = mtk_gpu_power[i].gpufreq_power;
  337. return (int) cur_gpu_power;
  338. }
  339. #if 0
  340. static void reset_gpu_power_history(void)
  341. {
  342. int i = 0;
  343. /* Be careful when this can be invoked and error values. */
  344. unsigned int max_gpu_power = mt_gpufreq_get_max_power();
  345. if (gpu_power_sma_len > MAX_GPU_POWER_SMA_LEN)
  346. gpu_power_sma_len = MAX_GPU_POWER_SMA_LEN;
  347. for (i = 0; i < MAX_GPU_POWER_SMA_LEN; i++)
  348. gpu_power_history[i] = max_gpu_power;
  349. gpu_power_history_idx = 0;
  350. }
  351. /* we'll calculate SMA for gpu power, but the output will still be aligned to OPP */
  352. static int adjust_gpu_power(int power)
  353. {
  354. int i, total = 0, sma_power;
  355. /* FIXME: debug only, this check should be moved to some setter functions.
  356. or deleted if we don't want sma_len is changeable during runtime */
  357. /*
  358. if (gpu_power_sma_len > MAX_GPU_POWER_SMA_LEN)
  359. gpu_power_sma_len = MAX_GPU_POWER_SMA_LEN;
  360. */
  361. if (power == 0)
  362. power = MAXIMUM_GPU_POWER;
  363. gpu_power_history[gpu_power_history_idx] = power;
  364. for (i = 0; i < gpu_power_sma_len; i++)
  365. total += gpu_power_history[i];
  366. gpu_power_history_idx = (gpu_power_history_idx + 1) % gpu_power_sma_len;
  367. sma_power = total / gpu_power_sma_len;
  368. for (i = 0; i < Num_of_GPU_OPP; i++) {
  369. if (mtk_gpu_power[i].gpufreq_power <= sma_power)
  370. break;
  371. }
  372. if (i >= Num_of_GPU_OPP)
  373. power = MINIMUM_GPU_POWER;
  374. else
  375. power = MAX(MINIMUM_GPU_POWER, (int)mtk_gpu_power[i].gpufreq_power);
  376. return power;
  377. }
  378. #endif
  379. #endif
  380. static int P_adaptive(int total_power, unsigned int gpu_loading)
  381. {
  382. /*
  383. Here the gpu_power is the gpu power limit for the next interval,
  384. not exactly what gpu power selected by GPU DVFS
  385. But the ground rule is real gpu power should always under gpu_power for the same time interval
  386. */
  387. static int cpu_power = 0, gpu_power;
  388. static int last_cpu_power = 0, last_gpu_power;
  389. last_cpu_power = cpu_power;
  390. last_gpu_power = gpu_power;
  391. g_total_power = total_power;
  392. if (total_power == 0) {
  393. cpu_power = gpu_power = 0;
  394. #if THERMAL_HEADROOM
  395. if (thp_max_cpu_power != 0)
  396. set_adaptive_cpu_power_limit((unsigned int)
  397. MAX(thp_max_cpu_power, MINIMUM_CPU_POWER));
  398. else
  399. set_adaptive_cpu_power_limit(0);
  400. #else
  401. set_adaptive_cpu_power_limit(0);
  402. #endif
  403. set_adaptive_gpu_power_limit(0);
  404. return 0;
  405. }
  406. if (total_power <= MINIMUM_TOTAL_POWER) {
  407. cpu_power = MINIMUM_CPU_POWER;
  408. gpu_power = MINIMUM_GPU_POWER;
  409. } else if (total_power >= MAXIMUM_TOTAL_POWER) {
  410. cpu_power = MAXIMUM_CPU_POWER;
  411. gpu_power = MAXIMUM_GPU_POWER;
  412. } else {
  413. int max_allowed_gpu_power =
  414. MIN((total_power - MINIMUM_CPU_POWER), MAXIMUM_GPU_POWER);
  415. int max_gpu_power = (int) mt_gpufreq_get_max_power();
  416. int highest_possible_gpu_power = (max_allowed_gpu_power > max_gpu_power) ? (max_gpu_power+1) : -1;
  417. /* int highest_possible_gpu_power_idx = 0; */
  418. int i = 0;
  419. unsigned int cur_gpu_freq = mt_gpufreq_get_cur_freq();
  420. /* int cur_idx = 0; */
  421. unsigned int cur_gpu_power = 0;
  422. unsigned int next_lower_gpu_power = 0;
  423. /* get GPU highest possible power and index and current power and index and next lower power */
  424. for (; i < Num_of_GPU_OPP; i++) {
  425. if ((mtk_gpu_power[i].gpufreq_power <= max_allowed_gpu_power) &&
  426. (-1 == highest_possible_gpu_power)) {
  427. /* choose OPP with power "<=" limit */
  428. highest_possible_gpu_power = mtk_gpu_power[i].gpufreq_power + 1;
  429. /* highest_possible_gpu_power_idx = i; */
  430. }
  431. if (mtk_gpu_power[i].gpufreq_khz == cur_gpu_freq) {
  432. next_lower_gpu_power = cur_gpu_power =
  433. (mtk_gpu_power[i].gpufreq_power + 1); /* choose OPP with power "<=" limit */
  434. /* cur_idx = i; */
  435. if ((i != Num_of_GPU_OPP - 1)
  436. && (mtk_gpu_power[i + 1].gpufreq_power >= MINIMUM_GPU_POWER)) {
  437. /* choose OPP with power "<=" limit */
  438. next_lower_gpu_power = mtk_gpu_power[i + 1].gpufreq_power + 1;
  439. }
  440. }
  441. }
  442. /* decide GPU power limit by loading */
  443. if (gpu_loading > GPU_L_H_TRIP) {
  444. gpu_power = highest_possible_gpu_power;
  445. } else if (gpu_loading <= GPU_L_L_TRIP) {
  446. gpu_power = MIN(next_lower_gpu_power, highest_possible_gpu_power);
  447. gpu_power = MAX(gpu_power, MINIMUM_GPU_POWER);
  448. } else {
  449. gpu_power = MIN(highest_possible_gpu_power, cur_gpu_power);
  450. }
  451. cpu_power = MIN((total_power - gpu_power), MAXIMUM_CPU_POWER);
  452. }
  453. #if 0
  454. /* TODO: check if this segment can be used in original design
  455. GPU SMA */
  456. if ((gpu_power_sma_len > 1) && (tscpu_atm == 3)) {
  457. total_power = gpu_power + cpu_power;
  458. gpu_power = adjust_gpu_power(gpu_power);
  459. cpu_power = total_power - gpu_power;
  460. }
  461. #endif
  462. if (cpu_power != last_cpu_power)
  463. set_adaptive_cpu_power_limit(cpu_power);
  464. if (gpu_power != last_gpu_power) {
  465. /* Work-around for unsync GPU power table problem 1. */
  466. if (gpu_power > mtk_gpu_power[0].gpufreq_power)
  467. set_adaptive_gpu_power_limit(0);
  468. else
  469. set_adaptive_gpu_power_limit(gpu_power);
  470. }
  471. tscpu_dprintk("%s cpu %d, gpu %d\n", __func__, cpu_power, gpu_power);
  472. return 0;
  473. }
  474. #if PRECISE_HYBRID_POWER_BUDGET
  475. static int __phpb_dynamic_theta(int max_theta)
  476. {
  477. int theta;
  478. /* temp solution as CATM
  479. FIXME: API? how to get tj trip? */
  480. int tj_trip = TARGET_TJS[0];
  481. if (TARGET_TJ <= tj_trip)
  482. theta = max_theta;
  483. else if (TARGET_TJ >= MAX_TARGET_TJ)
  484. theta = phpb_theta_min;
  485. else {
  486. theta = max_theta - (TARGET_TJ - tj_trip) *
  487. (max_theta - phpb_theta_min) /
  488. (MAX_TARGET_TJ - tj_trip);
  489. }
  490. return theta;
  491. }
  492. /**
  493. * TODO: target_tj is adjusted by catmv2, therefore dynamic_theta would not
  494. * changed frequently.
  495. */
  496. static int __phpb_calc_delta(int curr_temp, int prev_temp, int phpb_param_idx)
  497. {
  498. struct phpb_param *p = &phpb_params[phpb_param_idx];
  499. int tt = TARGET_TJ - curr_temp;
  500. int tp = prev_temp - curr_temp;
  501. int delta_power = 0, delta_power_tt, delta_power_tp;
  502. /* *2 is to cover Tj jump betwen [TTJ-tj_stable_range, TTJ+tj_stable_range] */
  503. if ((abs(tt) > tj_stable_range) || (abs(tp) > (tj_stable_range * 2))) {
  504. delta_power_tt = tt / p->tt;
  505. delta_power_tp = tp / p->tp;
  506. /* When Tj is rising, double power cut. */
  507. if (delta_power_tp < 0)
  508. delta_power_tp *= 2;
  509. delta_power = (delta_power_tt + delta_power_tp) /
  510. __phpb_dynamic_theta(phpb_theta_max);
  511. }
  512. return delta_power;
  513. }
  514. static int phpb_calc_delta(int curr_temp, int prev_temp)
  515. {
  516. int delta;
  517. if (tscpu_curr_cpu_temp >= tscpu_curr_gpu_temp)
  518. delta = __phpb_calc_delta(tscpu_curr_cpu_temp, tscpu_prev_cpu_temp, PHPB_PARAM_CPU);
  519. else
  520. delta = __phpb_calc_delta(tscpu_curr_gpu_temp, tscpu_prev_gpu_temp, PHPB_PARAM_GPU);
  521. return delta;
  522. }
  523. /* calculated total power based on current opp */
  524. static int get_total_curr_power(void)
  525. {
  526. int cpu_power = 0, gpu_power = 0;
  527. #ifdef ATM_USES_PPM
  528. cpu_power = (int) mt_ppm_thermal_get_cur_power() + 1; /* choose OPP with power "<=" limit */
  529. #else
  530. /* maybe you should disable PRECISE_HYBRID_POWER_BUDGET if current cpu power unavailable .*/
  531. cpu_power = 0;
  532. #endif
  533. /* avoid idle power too small to hurt another unit performance */
  534. if (cpu_power < MINIMUM_CPU_POWER)
  535. cpu_power = MINIMUM_CPU_POWER;
  536. gpu_power = _get_current_gpu_power() + 1; /* choose OPP with power "<=" limit */
  537. if (gpu_power < MINIMUM_GPU_POWER)
  538. gpu_power = MINIMUM_GPU_POWER;
  539. return cpu_power + gpu_power;
  540. }
  541. static int phpb_calc_total(int prev_total_power, long curr_temp, long prev_temp)
  542. {
  543. /* total_power is new power limit, which curr_power is current power
  544. * calculated based on current opp */
  545. int delta_power, total_power, curr_power;
  546. delta_power = phpb_calc_delta(curr_temp, prev_temp);
  547. if (delta_power == 0)
  548. return prev_total_power;
  549. curr_power = get_total_curr_power();
  550. /* In some conditions, we will consider using current request power to
  551. * avoid giving unlimit power budget.
  552. * Temp. rising is large, requset power is of course less than power
  553. * limit (but it sometime goes over...)
  554. */
  555. if ((curr_temp - prev_temp) >= tj_jump_threshold &&
  556. curr_power < prev_total_power)
  557. total_power = curr_power + delta_power;
  558. else
  559. total_power = prev_total_power + delta_power;
  560. total_power = clamp(total_power, MINIMUM_TOTAL_POWER, MAXIMUM_TOTAL_POWER);
  561. return total_power;
  562. }
  563. static int _adaptive_power_ppb(long prev_temp, long curr_temp, unsigned int gpu_loading)
  564. {
  565. static int triggered, total_power;
  566. int delta_power = 0;
  567. if (cl_dev_adp_cpu_state_active == 1) {
  568. tscpu_dprintk("%s %d %d %d %d %d %d %d\n", __func__,
  569. PACKAGE_THETA_JA_RISE, PACKAGE_THETA_JA_FALL, MINIMUM_BUDGET_CHANGE,
  570. MINIMUM_CPU_POWER, MAXIMUM_CPU_POWER, MINIMUM_GPU_POWER, MAXIMUM_GPU_POWER);
  571. /* Check if it is triggered */
  572. if (!triggered) {
  573. triggered = 1;
  574. total_power = phpb_calc_total(get_total_curr_power(), curr_temp, prev_temp);
  575. tscpu_dprintk("%s triggered:0->1 Tp %ld, Tc %ld, TARGET_TJ %d, Pt %d\n",
  576. __func__, prev_temp, curr_temp, TARGET_TJ, total_power);
  577. return P_adaptive(total_power, gpu_loading);
  578. }
  579. /* Adjust total power budget if necessary */
  580. total_power = phpb_calc_total(total_power, curr_temp, prev_temp);
  581. /* TODO: delta_power is not changed but printed. */
  582. tscpu_dprintk("%s TARGET_TJ %d, delta_power %d, total_power %d\n",
  583. __func__, TARGET_TJ, delta_power, total_power);
  584. tscpu_dprintk("%s Tp %ld, Tc %ld, Pt %d\n", __func__, prev_temp, curr_temp, total_power);
  585. return P_adaptive(total_power, gpu_loading);
  586. /* end of cl_dev_adp_cpu_state_active == 1 */
  587. } else {
  588. if (triggered) {
  589. triggered = 0;
  590. tscpu_dprintk("%s Tp %ld, Tc %ld, Pt %d\n", __func__, prev_temp, curr_temp, total_power);
  591. return P_adaptive(0, 0);
  592. #if THERMAL_HEADROOM
  593. } else {
  594. if (thp_max_cpu_power != 0)
  595. set_adaptive_cpu_power_limit((unsigned int) MAX(thp_max_cpu_power, MINIMUM_CPU_POWER));
  596. else
  597. set_adaptive_cpu_power_limit(0);
  598. }
  599. #else
  600. }
  601. #endif
  602. /* reset_gpu_power_history(); */
  603. }
  604. return 0;
  605. }
  606. #endif
  607. static int _adaptive_power(long prev_temp, long curr_temp, unsigned int gpu_loading)
  608. {
  609. static int triggered = 0, total_power;
  610. int delta_power = 0;
  611. if (cl_dev_adp_cpu_state_active == 1) {
  612. tscpu_dprintk("%s %d %d %d %d %d %d %d %d\n", __func__,
  613. FIRST_STEP_TOTAL_POWER_BUDGET, PACKAGE_THETA_JA_RISE,
  614. PACKAGE_THETA_JA_FALL, MINIMUM_BUDGET_CHANGE, MINIMUM_CPU_POWER,
  615. MAXIMUM_CPU_POWER, MINIMUM_GPU_POWER, MAXIMUM_GPU_POWER);
  616. /* Check if it is triggered */
  617. if (!triggered) {
  618. if (curr_temp < TARGET_TJ)
  619. return 0;
  620. triggered = 1;
  621. switch (tscpu_atm) {
  622. case 1: /* FTL ATM v2 */
  623. case 2: /* CPU_GPU_Weight ATM v2 */
  624. #if MTKTSCPU_FAST_POLLING
  625. total_power =
  626. FIRST_STEP_TOTAL_POWER_BUDGET -
  627. ((curr_temp - TARGET_TJ) * tt_ratio_high_rise +
  628. (curr_temp - prev_temp) * tp_ratio_high_rise) /
  629. (PACKAGE_THETA_JA_RISE * tscpu_cur_fp_factor);
  630. #else
  631. total_power =
  632. FIRST_STEP_TOTAL_POWER_BUDGET -
  633. ((curr_temp - TARGET_TJ) * tt_ratio_high_rise +
  634. (curr_temp - prev_temp) * tp_ratio_high_rise) /
  635. PACKAGE_THETA_JA_RISE;
  636. #endif
  637. break;
  638. case 0:
  639. default: /* ATM v1 */
  640. total_power = FIRST_STEP_TOTAL_POWER_BUDGET;
  641. }
  642. tscpu_dprintk("%s Tp %ld, Tc %ld, Pt %d\n", __func__, prev_temp, curr_temp, total_power);
  643. return P_adaptive(total_power, gpu_loading);
  644. }
  645. /* Adjust total power budget if necessary */
  646. switch (tscpu_atm) {
  647. case 1: /* FTL ATM v2 */
  648. case 2: /* CPU_GPU_Weight ATM v2 */
  649. if ((curr_temp >= TARGET_TJ_HIGH) && (curr_temp > prev_temp)) {
  650. #if MTKTSCPU_FAST_POLLING
  651. total_power -=
  652. MAX(((curr_temp - TARGET_TJ) * tt_ratio_high_rise +
  653. (curr_temp -
  654. prev_temp) * tp_ratio_high_rise) /
  655. (PACKAGE_THETA_JA_RISE * tscpu_cur_fp_factor),
  656. MINIMUM_BUDGET_CHANGE);
  657. #else
  658. total_power -=
  659. MAX(((curr_temp - TARGET_TJ) * tt_ratio_high_rise +
  660. (curr_temp -
  661. prev_temp) * tp_ratio_high_rise) / PACKAGE_THETA_JA_RISE,
  662. MINIMUM_BUDGET_CHANGE);
  663. #endif
  664. } else if ((curr_temp >= TARGET_TJ_HIGH) && (curr_temp <= prev_temp)) {
  665. #if MTKTSCPU_FAST_POLLING
  666. total_power -=
  667. MAX(((curr_temp - TARGET_TJ) * tt_ratio_high_fall -
  668. (prev_temp -
  669. curr_temp) * tp_ratio_high_fall) /
  670. (PACKAGE_THETA_JA_FALL * tscpu_cur_fp_factor),
  671. MINIMUM_BUDGET_CHANGE);
  672. #else
  673. total_power -=
  674. MAX(((curr_temp - TARGET_TJ) * tt_ratio_high_fall -
  675. (prev_temp -
  676. curr_temp) * tp_ratio_high_fall) / PACKAGE_THETA_JA_FALL,
  677. MINIMUM_BUDGET_CHANGE);
  678. #endif
  679. } else if ((curr_temp <= TARGET_TJ_LOW) && (curr_temp > prev_temp)) {
  680. #if MTKTSCPU_FAST_POLLING
  681. total_power +=
  682. MAX(((TARGET_TJ - curr_temp) * tt_ratio_low_rise -
  683. (curr_temp -
  684. prev_temp) * tp_ratio_low_rise) / (PACKAGE_THETA_JA_RISE *
  685. tscpu_cur_fp_factor),
  686. MINIMUM_BUDGET_CHANGE);
  687. #else
  688. total_power +=
  689. MAX(((TARGET_TJ - curr_temp) * tt_ratio_low_rise -
  690. (curr_temp -
  691. prev_temp) * tp_ratio_low_rise) / PACKAGE_THETA_JA_RISE,
  692. MINIMUM_BUDGET_CHANGE);
  693. #endif
  694. } else if ((curr_temp <= TARGET_TJ_LOW) && (curr_temp <= prev_temp)) {
  695. #if MTKTSCPU_FAST_POLLING
  696. total_power +=
  697. MAX(((TARGET_TJ - curr_temp) * tt_ratio_low_fall +
  698. (prev_temp -
  699. curr_temp) * tp_ratio_low_fall) / (PACKAGE_THETA_JA_FALL *
  700. tscpu_cur_fp_factor),
  701. MINIMUM_BUDGET_CHANGE);
  702. #else
  703. total_power +=
  704. MAX(((TARGET_TJ - curr_temp) * tt_ratio_low_fall +
  705. (prev_temp -
  706. curr_temp) * tp_ratio_low_fall) / PACKAGE_THETA_JA_FALL,
  707. MINIMUM_BUDGET_CHANGE);
  708. #endif
  709. }
  710. total_power =
  711. (total_power > MINIMUM_TOTAL_POWER) ? total_power : MINIMUM_TOTAL_POWER;
  712. total_power =
  713. (total_power < MAXIMUM_TOTAL_POWER) ? total_power : MAXIMUM_TOTAL_POWER;
  714. break;
  715. case 0:
  716. default: /* ATM v1 */
  717. if ((curr_temp > TARGET_TJ_HIGH) && (curr_temp >= prev_temp)) {
  718. #if MTKTSCPU_FAST_POLLING
  719. delta_power =
  720. (curr_temp -
  721. prev_temp) / (PACKAGE_THETA_JA_RISE * tscpu_cur_fp_factor);
  722. #else
  723. delta_power = (curr_temp - prev_temp) / PACKAGE_THETA_JA_RISE;
  724. #endif
  725. if (prev_temp > TARGET_TJ_HIGH) {
  726. delta_power =
  727. (delta_power >
  728. MINIMUM_BUDGET_CHANGE) ? delta_power :
  729. MINIMUM_BUDGET_CHANGE;
  730. }
  731. total_power -= delta_power;
  732. total_power =
  733. (total_power >
  734. MINIMUM_TOTAL_POWER) ? total_power : MINIMUM_TOTAL_POWER;
  735. }
  736. if ((curr_temp < TARGET_TJ_LOW) && (curr_temp <= prev_temp)) {
  737. #if MTKTSCPU_FAST_POLLING
  738. delta_power =
  739. (prev_temp -
  740. curr_temp) / (PACKAGE_THETA_JA_FALL * tscpu_cur_fp_factor);
  741. #else
  742. delta_power = (prev_temp - curr_temp) / PACKAGE_THETA_JA_FALL;
  743. #endif
  744. if (prev_temp < TARGET_TJ_LOW) {
  745. delta_power =
  746. (delta_power >
  747. MINIMUM_BUDGET_CHANGE) ? delta_power :
  748. MINIMUM_BUDGET_CHANGE;
  749. }
  750. total_power += delta_power;
  751. total_power =
  752. (total_power <
  753. MAXIMUM_TOTAL_POWER) ? total_power : MAXIMUM_TOTAL_POWER;
  754. }
  755. break;
  756. }
  757. tscpu_dprintk("%s Tp %ld, Tc %ld, Pt %d\n", __func__, prev_temp, curr_temp,
  758. total_power);
  759. return P_adaptive(total_power, gpu_loading);
  760. }
  761. #if CONTINUOUS_TM
  762. else if ((cl_dev_adp_cpu_state_active == 1) && (ctm_on) && (curr_temp < current_ETJ)) {
  763. tscpu_printk("CTM exit curr_temp %d cetj %d\n", TARGET_TJ, current_ETJ);
  764. /* even cooler not exit, when CTM is on and current Tj < current_ETJ, leave ATM */
  765. if (triggered) {
  766. triggered = 0;
  767. tscpu_dprintk("%s Tp %ld, Tc %ld, Pt %d\n", __func__, prev_temp, curr_temp,
  768. total_power);
  769. return P_adaptive(0, 0);
  770. }
  771. #if THERMAL_HEADROOM
  772. else {
  773. if (thp_max_cpu_power != 0)
  774. set_adaptive_cpu_power_limit((unsigned int)
  775. MAX(thp_max_cpu_power,
  776. MINIMUM_CPU_POWER));
  777. else
  778. set_adaptive_cpu_power_limit(0);
  779. }
  780. #endif
  781. }
  782. #endif
  783. else {
  784. if (triggered) {
  785. triggered = 0;
  786. tscpu_dprintk("%s Tp %ld, Tc %ld, Pt %d\n", __func__, prev_temp, curr_temp,
  787. total_power);
  788. return P_adaptive(0, 0);
  789. }
  790. #if THERMAL_HEADROOM
  791. else {
  792. if (thp_max_cpu_power != 0)
  793. set_adaptive_cpu_power_limit((unsigned int)
  794. MAX(thp_max_cpu_power,
  795. MINIMUM_CPU_POWER));
  796. else
  797. set_adaptive_cpu_power_limit(0);
  798. }
  799. #endif
  800. }
  801. return 0;
  802. }
  803. static int decide_ttj(void)
  804. {
  805. int i = 0;
  806. int active_cooler_id = -1;
  807. int ret = 117000; /* highest allowable TJ */
  808. int temp_cl_dev_adp_cpu_state_active = 0;
  809. for (; i < MAX_CPT_ADAPTIVE_COOLERS; i++) {
  810. if (cl_dev_adp_cpu_state[i]) {
  811. ret = MIN(ret, TARGET_TJS[i]);
  812. temp_cl_dev_adp_cpu_state_active = 1;
  813. if (ret == TARGET_TJS[i])
  814. active_cooler_id = i;
  815. }
  816. }
  817. cl_dev_adp_cpu_state_active = temp_cl_dev_adp_cpu_state_active;
  818. TARGET_TJ = ret;
  819. #if CONTINUOUS_TM
  820. if (ctm_on) {
  821. int curr_tpcb = mtk_thermal_get_temp(MTK_THERMAL_SENSOR_AP);
  822. if (ctm_on == 1) {
  823. TARGET_TJ =
  824. MIN(MAX_TARGET_TJ,
  825. MAX(STEADY_TARGET_TJ, (COEF_AE - COEF_BE * curr_tpcb / 1000)));
  826. } else if (ctm_on == 2) {
  827. /* +++ cATM+ +++ */
  828. TARGET_TJ = ta_get_ttj();
  829. /* --- cATM+ --- */
  830. }
  831. current_ETJ =
  832. MIN(MAX_EXIT_TJ, MAX(STEADY_EXIT_TJ, (COEF_AX - COEF_BX * curr_tpcb / 1000)));
  833. /* tscpu_printk("cttj %d cetj %d tpcb %d\n", TARGET_TJ, current_ETJ, curr_tpcb); */
  834. }
  835. #endif
  836. cpu_target_tj = TARGET_TJ;
  837. #if CONTINUOUS_TM
  838. cpu_target_offset = TARGET_TJ - current_ETJ;
  839. #endif
  840. TARGET_TJ_HIGH = TARGET_TJ + 1000;
  841. TARGET_TJ_LOW = TARGET_TJ - 1000;
  842. if (0 <= active_cooler_id && MAX_CPT_ADAPTIVE_COOLERS > active_cooler_id) {
  843. PACKAGE_THETA_JA_RISE = PACKAGE_THETA_JA_RISES[active_cooler_id];
  844. PACKAGE_THETA_JA_FALL = PACKAGE_THETA_JA_FALLS[active_cooler_id];
  845. MINIMUM_CPU_POWER = MINIMUM_CPU_POWERS[active_cooler_id];
  846. MAXIMUM_CPU_POWER = MAXIMUM_CPU_POWERS[active_cooler_id];
  847. /* get GPU min/max power from GPU DVFS should be
  848. done when configuring ATM instead of decide_ttj */
  849. #if 0
  850. {
  851. MAXIMUM_GPU_POWER = (int)mt_gpufreq_get_max_power();
  852. MINIMUM_GPU_POWER = (int)mt_gpufreq_get_min_power();
  853. tscpu_printk("decide_ttj: MAXIMUM_GPU_POWER=%d,MINIMUM_GPU_POWER=%d\n",
  854. MAXIMUM_GPU_POWER, MINIMUM_GPU_POWER);
  855. }
  856. #else
  857. MINIMUM_GPU_POWER = MINIMUM_GPU_POWERS[active_cooler_id];
  858. MAXIMUM_GPU_POWER = MAXIMUM_GPU_POWERS[active_cooler_id];
  859. #endif
  860. MINIMUM_TOTAL_POWER = MINIMUM_CPU_POWER + MINIMUM_GPU_POWER;
  861. MAXIMUM_TOTAL_POWER = MAXIMUM_CPU_POWER + MAXIMUM_GPU_POWER;
  862. FIRST_STEP_TOTAL_POWER_BUDGET = FIRST_STEP_TOTAL_POWER_BUDGETS[active_cooler_id];
  863. MINIMUM_BUDGET_CHANGE = MINIMUM_BUDGET_CHANGES[active_cooler_id];
  864. } else {
  865. MINIMUM_CPU_POWER = MINIMUM_CPU_POWERS[0];
  866. MAXIMUM_CPU_POWER = MAXIMUM_CPU_POWERS[0];
  867. }
  868. #if THERMAL_HEADROOM
  869. MAXIMUM_CPU_POWER -= p_Tpcb_correlation * MAX((bts_cur_temp - Tpcb_trip_point), 0) / 1000;
  870. /* tscpu_printk("max_cpu_pwr %d %d\n", bts_cur_temp, MAXIMUM_CPU_POWER); */
  871. /* TODO: use 0 as current P */
  872. thp_max_cpu_power = (thp_threshold_tj - tscpu_read_curr_temp) * thp_p_tj_correlation / 1000 + 0;
  873. if (thp_max_cpu_power != 0)
  874. MAXIMUM_CPU_POWER = MIN(MAXIMUM_CPU_POWER, thp_max_cpu_power);
  875. MAXIMUM_CPU_POWER = MAX(MAXIMUM_CPU_POWER, MINIMUM_CPU_POWER);
  876. /* tscpu_printk("thp max_cpu_pwr %d %d\n", thp_max_cpu_power, MAXIMUM_CPU_POWER); */
  877. #endif
  878. return ret;
  879. }
  880. #endif
  881. #if CPT_ADAPTIVE_AP_COOLER
  882. static int adp_cpu_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state)
  883. {
  884. /* tscpu_dprintk("adp_cpu_get_max_state\n"); */
  885. *state = 1;
  886. return 0;
  887. }
  888. static int adp_cpu_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state)
  889. {
  890. /* tscpu_dprintk("adp_cpu_get_cur_state\n"); */
  891. *state = cl_dev_adp_cpu_state[(cdev->type[13] - '0')];
  892. /* *state = cl_dev_adp_cpu_state; */
  893. return 0;
  894. }
  895. static int adp_cpu_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
  896. {
  897. int ttj = 117000;
  898. cl_dev_adp_cpu_state[(cdev->type[13] - '0')] = state;
  899. ttj = decide_ttj(); /* TODO: no exit point can be obtained in mtk_ts_cpu.c */
  900. /* tscpu_dprintk("adp_cpu_set_cur_state[%d] =%d, ttj=%d\n", (cdev->type[13] - '0'), state, ttj); */
  901. if (active_adp_cooler == (int)(cdev->type[13] - '0')) {
  902. /* = (NULL == mtk_thermal_get_gpu_loading_fp) ? 0 : mtk_thermal_get_gpu_loading_fp(); */
  903. unsigned int gpu_loading;
  904. if (!mtk_get_gpu_loading(&gpu_loading))
  905. gpu_loading = 0;
  906. _adaptive_power_calc(tscpu_g_prev_temp, tscpu_g_curr_temp, (unsigned int) gpu_loading);
  907. }
  908. return 0;
  909. }
  910. #endif
  911. #if CPT_ADAPTIVE_AP_COOLER
  912. static struct thermal_cooling_device_ops mtktscpu_cooler_adp_cpu_ops = {
  913. .get_max_state = adp_cpu_get_max_state,
  914. .get_cur_state = adp_cpu_get_cur_state,
  915. .set_cur_state = adp_cpu_set_cur_state,
  916. };
  917. #endif
  918. #if CPT_ADAPTIVE_AP_COOLER
  919. static int tscpu_read_atm_setting(struct seq_file *m, void *v)
  920. {
  921. int i;
  922. for (i = 0; i < MAX_CPT_ADAPTIVE_COOLERS; i++) {
  923. seq_printf(m, "%s%02d\n", adaptive_cooler_name, i);
  924. seq_printf(m, " first_step = %d\n", FIRST_STEP_TOTAL_POWER_BUDGETS[i]);
  925. seq_printf(m, " theta rise = %d\n", PACKAGE_THETA_JA_RISES[i]);
  926. seq_printf(m, " theta fall = %d\n", PACKAGE_THETA_JA_FALLS[i]);
  927. seq_printf(m, " min_budget_change = %d\n", MINIMUM_BUDGET_CHANGES[i]);
  928. seq_printf(m, " m cpu = %d\n", MINIMUM_CPU_POWERS[i]);
  929. seq_printf(m, " M cpu = %d\n", MAXIMUM_CPU_POWERS[i]);
  930. seq_printf(m, " m gpu = %d\n", MINIMUM_GPU_POWERS[i]);
  931. seq_printf(m, " M gpu = %d\n", MAXIMUM_GPU_POWERS[i]);
  932. }
  933. return 0;
  934. }
  935. static ssize_t tscpu_write_atm_setting(struct file *file, const char __user *buffer, size_t count,
  936. loff_t *data)
  937. {
  938. char desc[128];
  939. /* char arg_name[32] = {0}; */
  940. /* int arg_val = 0; */
  941. int len = 0;
  942. int i_id = -1, i_first_step = -1, i_theta_r = -1, i_theta_f = -1, i_budget_change =
  943. -1, i_min_cpu_pwr = -1, i_max_cpu_pwr = -1, i_min_gpu_pwr = -1, i_max_gpu_pwr = -1;
  944. len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
  945. if (copy_from_user(desc, buffer, len))
  946. return 0;
  947. desc[len] = '\0';
  948. if (9 <= sscanf(desc, "%d %d %d %d %d %d %d %d %d", &i_id, &i_first_step, &i_theta_r, &i_theta_f,
  949. &i_budget_change, &i_min_cpu_pwr, &i_max_cpu_pwr, &i_min_gpu_pwr,
  950. &i_max_gpu_pwr)) {
  951. tscpu_printk("tscpu_write_atm_setting input %d %d %d %d %d %d %d %d %d\n", i_id,
  952. i_first_step, i_theta_r, i_theta_f, i_budget_change, i_min_cpu_pwr,
  953. i_max_cpu_pwr, i_min_gpu_pwr, i_max_gpu_pwr);
  954. if (i_id >= 0 && i_id < MAX_CPT_ADAPTIVE_COOLERS) {
  955. if (i_first_step > 0)
  956. FIRST_STEP_TOTAL_POWER_BUDGETS[i_id] = i_first_step;
  957. else
  958. #ifdef CONFIG_MTK_AEE_FEATURE
  959. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  960. "tscpu_write_atm_setting", "Wrong thermal policy");
  961. #endif
  962. if (i_theta_r > 0)
  963. PACKAGE_THETA_JA_RISES[i_id] = i_theta_r;
  964. else
  965. #ifdef CONFIG_MTK_AEE_FEATURE
  966. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  967. "tscpu_write_atm_setting", "Wrong thermal policy");
  968. #endif
  969. if (i_theta_f > 0)
  970. PACKAGE_THETA_JA_FALLS[i_id] = i_theta_f;
  971. else
  972. #ifdef CONFIG_MTK_AEE_FEATURE
  973. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  974. "tscpu_write_atm_setting", "Wrong thermal policy");
  975. #endif
  976. if (i_budget_change >= 0)
  977. MINIMUM_BUDGET_CHANGES[i_id] = i_budget_change;
  978. else
  979. #ifdef CONFIG_MTK_AEE_FEATURE
  980. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  981. "tscpu_write_atm_setting", "Wrong thermal policy");
  982. #endif
  983. if (i_min_cpu_pwr > 0)
  984. MINIMUM_CPU_POWERS[i_id] = i_min_cpu_pwr;
  985. #ifdef ATM_USES_PPM
  986. else if (i_min_cpu_pwr == 0)
  987. MINIMUM_CPU_POWERS[i_id] = mt_ppm_thermal_get_min_power() + 1;
  988. /* choose OPP with power "<=" limit */
  989. #endif
  990. else
  991. #ifdef CONFIG_MTK_AEE_FEATURE
  992. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  993. "tscpu_write_atm_setting", "Wrong thermal policy");
  994. #endif
  995. if (i_max_cpu_pwr > 0)
  996. MAXIMUM_CPU_POWERS[i_id] = i_max_cpu_pwr;
  997. #ifdef ATM_USES_PPM
  998. else if (i_max_cpu_pwr == 0)
  999. MAXIMUM_CPU_POWERS[i_id] = mt_ppm_thermal_get_max_power() + 1;
  1000. /* choose OPP with power "<=" limit */
  1001. #endif
  1002. else
  1003. #ifdef CONFIG_MTK_AEE_FEATURE
  1004. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  1005. "tscpu_write_atm_setting", "Wrong thermal policy");
  1006. #endif
  1007. if (i_min_gpu_pwr > 0) {
  1008. /* choose OPP with power "<=" limit */
  1009. int min_gpuopp_power = (int) mt_gpufreq_get_min_power() + 1;
  1010. MINIMUM_GPU_POWERS[i_id] = MAX(i_min_gpu_pwr, min_gpuopp_power);
  1011. } else if (i_min_gpu_pwr == 0)
  1012. MINIMUM_GPU_POWERS[i_id] = (int) mt_gpufreq_get_min_power() + 1;
  1013. /* choose OPP with power "<=" limit */
  1014. else
  1015. #ifdef CONFIG_MTK_AEE_FEATURE
  1016. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  1017. "tscpu_write_atm_setting", "Wrong thermal policy");
  1018. #endif
  1019. if (i_max_gpu_pwr > 0) {
  1020. /* choose OPP with power "<=" limit */
  1021. int min_gpuopp_power = (int) mt_gpufreq_get_min_power() + 1;
  1022. MAXIMUM_GPU_POWERS[i_id] = MAX(i_max_gpu_pwr, min_gpuopp_power);
  1023. } else if (i_max_gpu_pwr == 0)
  1024. MAXIMUM_GPU_POWERS[i_id] = (int) mt_gpufreq_get_max_power() + 1;
  1025. /* choose OPP with power "<=" limit */
  1026. else
  1027. #ifdef CONFIG_MTK_AEE_FEATURE
  1028. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  1029. "tscpu_write_atm_setting", "Wrong thermal policy");
  1030. #endif
  1031. active_adp_cooler = i_id;
  1032. tscpu_printk("tscpu_write_dtm_setting applied %d %d %d %d %d %d %d %d %d\n",
  1033. i_id, FIRST_STEP_TOTAL_POWER_BUDGETS[i_id],
  1034. PACKAGE_THETA_JA_RISES[i_id], PACKAGE_THETA_JA_FALLS[i_id],
  1035. MINIMUM_BUDGET_CHANGES[i_id], MINIMUM_CPU_POWERS[i_id],
  1036. MAXIMUM_CPU_POWERS[i_id], MINIMUM_GPU_POWERS[i_id],
  1037. MAXIMUM_GPU_POWERS[i_id]);
  1038. } else {
  1039. #ifdef CONFIG_MTK_AEE_FEATURE
  1040. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  1041. "tscpu_write_atm_setting", "Wrong thermal policy");
  1042. #endif
  1043. }
  1044. return count;
  1045. }
  1046. tscpu_dprintk("tscpu_write_dtm_setting bad argument\n");
  1047. return -EINVAL;
  1048. }
  1049. static int tscpu_read_gpu_threshold(struct seq_file *m, void *v)
  1050. {
  1051. seq_printf(m, "H %d L %d\n", GPU_L_H_TRIP, GPU_L_L_TRIP);
  1052. return 0;
  1053. }
  1054. static ssize_t tscpu_write_gpu_threshold(struct file *file, const char __user *buffer,
  1055. size_t count, loff_t *data)
  1056. {
  1057. char desc[128];
  1058. int len = 0;
  1059. int gpu_h = -1, gpu_l = -1;
  1060. len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
  1061. if (copy_from_user(desc, buffer, len))
  1062. return 0;
  1063. desc[len] = '\0';
  1064. if (2 <= sscanf(desc, "%d %d", &gpu_h, &gpu_l)) {
  1065. tscpu_printk("tscpu_write_gpu_threshold input %d %d\n", gpu_h, gpu_l);
  1066. if ((gpu_h > 0) && (gpu_l > 0) && (gpu_h > gpu_l)) {
  1067. GPU_L_H_TRIP = gpu_h;
  1068. GPU_L_L_TRIP = gpu_l;
  1069. tscpu_printk("tscpu_write_gpu_threshold applied %d %d\n", GPU_L_H_TRIP,
  1070. GPU_L_L_TRIP);
  1071. } else {
  1072. tscpu_dprintk("tscpu_write_gpu_threshold out of range\n");
  1073. }
  1074. return count;
  1075. }
  1076. tscpu_dprintk("tscpu_write_gpu_threshold bad argument\n");
  1077. return -EINVAL;
  1078. }
  1079. /* +ASC+ */
  1080. static int tscpu_read_atm(struct seq_file *m, void *v)
  1081. {
  1082. seq_printf(m, "[tscpu_read_atm] ver = %d\n", tscpu_atm);
  1083. seq_printf(m, "tt_ratio_high_rise = %d\n", tt_ratio_high_rise);
  1084. seq_printf(m, "tt_ratio_high_fall = %d\n", tt_ratio_high_fall);
  1085. seq_printf(m, "tt_ratio_low_rise = %d\n", tt_ratio_low_rise);
  1086. seq_printf(m, "tt_ratio_low_fall = %d\n", tt_ratio_low_fall);
  1087. seq_printf(m, "tp_ratio_high_rise = %d\n", tp_ratio_high_rise);
  1088. seq_printf(m, "tp_ratio_high_fall = %d\n", tp_ratio_high_fall);
  1089. seq_printf(m, "tp_ratio_low_rise = %d\n", tp_ratio_low_rise);
  1090. seq_printf(m, "tp_ratio_low_fall = %d\n", tp_ratio_low_fall);
  1091. return 0;
  1092. }
  1093. /* -ASC- */
  1094. /* +ASC+ */
  1095. static ssize_t tscpu_write_atm(struct file *file, const char __user *buffer, size_t count,
  1096. loff_t *data)
  1097. {
  1098. char desc[128];
  1099. int atm_ver;
  1100. int tmp_tt_ratio_high_rise;
  1101. int tmp_tt_ratio_high_fall;
  1102. int tmp_tt_ratio_low_rise;
  1103. int tmp_tt_ratio_low_fall;
  1104. int tmp_tp_ratio_high_rise;
  1105. int tmp_tp_ratio_high_fall;
  1106. int tmp_tp_ratio_low_rise;
  1107. int tmp_tp_ratio_low_fall;
  1108. int len = 0;
  1109. len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
  1110. if (copy_from_user(desc, buffer, len))
  1111. return 0;
  1112. desc[len] = '\0';
  1113. if (sscanf(desc, "%d %d %d %d %d %d %d %d %d ",
  1114. &atm_ver, &tmp_tt_ratio_high_rise, &tmp_tt_ratio_high_fall,
  1115. &tmp_tt_ratio_low_rise, &tmp_tt_ratio_low_fall, &tmp_tp_ratio_high_rise,
  1116. &tmp_tp_ratio_high_fall, &tmp_tp_ratio_low_rise, &tmp_tp_ratio_low_fall) == 9)
  1117. /* if (5 <= sscanf(desc, "%d %d %d %d %d", &log_switch, &hot, &normal, &low, &lv_offset)) */
  1118. {
  1119. tscpu_atm = atm_ver;
  1120. tt_ratio_high_rise = tmp_tt_ratio_high_rise;
  1121. tt_ratio_high_fall = tmp_tt_ratio_high_fall;
  1122. tt_ratio_low_rise = tmp_tt_ratio_low_rise;
  1123. tt_ratio_low_fall = tmp_tt_ratio_low_fall;
  1124. tp_ratio_high_rise = tmp_tp_ratio_high_rise;
  1125. tp_ratio_high_fall = tmp_tp_ratio_high_fall;
  1126. tp_ratio_low_rise = tmp_tp_ratio_low_rise;
  1127. tp_ratio_low_fall = tmp_tp_ratio_low_fall;
  1128. #if PRECISE_HYBRID_POWER_BUDGET
  1129. if (tscpu_atm == 3)
  1130. _adaptive_power_calc = _adaptive_power_ppb;
  1131. else
  1132. _adaptive_power_calc = _adaptive_power;
  1133. #endif
  1134. return count;
  1135. }
  1136. tscpu_printk("tscpu_write_atm bad argument\n");
  1137. return -EINVAL;
  1138. }
  1139. /* -ASC- */
  1140. #if THERMAL_HEADROOM
  1141. static int tscpu_read_thp(struct seq_file *m, void *v)
  1142. {
  1143. seq_printf(m, "Tpcb pt coef %d\n", p_Tpcb_correlation);
  1144. seq_printf(m, "Tpcb threshold %d\n", Tpcb_trip_point);
  1145. seq_printf(m, "Tj pt coef %d\n", thp_p_tj_correlation);
  1146. seq_printf(m, "thp tj threshold %d\n", thp_threshold_tj);
  1147. return 0;
  1148. }
  1149. static ssize_t tscpu_write_thp(struct file *file, const char __user *buffer, size_t count,
  1150. loff_t *data)
  1151. {
  1152. char desc[128];
  1153. int len = 0;
  1154. int tpcb_coef = -1, tpcb_trip = -1, thp_coef = -1, thp_threshold = -1;
  1155. len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
  1156. if (copy_from_user(desc, buffer, len))
  1157. return 0;
  1158. desc[len] = '\0';
  1159. if (4 <= sscanf(desc, "%d %d %d %d", &tpcb_coef, &tpcb_trip, &thp_coef, &thp_threshold)) {
  1160. tscpu_printk("%s input %d %d\n", __func__, tpcb_coef, tpcb_trip, thp_coef,
  1161. thp_threshold);
  1162. p_Tpcb_correlation = tpcb_coef;
  1163. Tpcb_trip_point = tpcb_trip;
  1164. thp_p_tj_correlation = thp_coef;
  1165. thp_threshold_tj = thp_threshold;
  1166. return count;
  1167. }
  1168. tscpu_dprintk("%s bad argument\n", __func__);
  1169. return -EINVAL;
  1170. }
  1171. #endif
  1172. #if CONTINUOUS_TM
  1173. static int tscpu_read_ctm(struct seq_file *m, void *v)
  1174. {
  1175. seq_printf(m, "ctm %d\n", ctm_on);
  1176. seq_printf(m, "Target Tj 0 %d\n", MAX_TARGET_TJ);
  1177. seq_printf(m, "Target Tj 2 %d\n", STEADY_TARGET_TJ);
  1178. seq_printf(m, "Tpcb 1 %d\n", TRIP_TPCB);
  1179. seq_printf(m, "Tpcb 2 %d\n", STEADY_TARGET_TPCB);
  1180. seq_printf(m, "Exit Tj 0 %d\n", MAX_EXIT_TJ);
  1181. seq_printf(m, "Exit Tj 2 %d\n", STEADY_EXIT_TJ);
  1182. seq_printf(m, "Enter_a %d\n", COEF_AE);
  1183. seq_printf(m, "Enter_b %d\n", COEF_BE);
  1184. seq_printf(m, "Exit_a %d\n", COEF_AX);
  1185. seq_printf(m, "Exit_b %d\n", COEF_BX);
  1186. /* +++ cATM+ parameters +++ */
  1187. seq_printf(m, "K_TT %d\n", K_TT);
  1188. seq_printf(m, "MAX_K_SUM_TT %d\n", MAX_K_SUM_TT);
  1189. seq_printf(m, "K_SUM_TT_LOW %d\n", K_SUM_TT_LOW);
  1190. seq_printf(m, "K_SUM_TT_HIGH %d\n", K_SUM_TT_HIGH);
  1191. seq_printf(m, "MIN_SUM_TT %d\n", MIN_SUM_TT);
  1192. seq_printf(m, "MAX_SUM_TT %d\n", MAX_SUM_TT);
  1193. seq_printf(m, "MIN_TTJ %d\n", MIN_TTJ);
  1194. seq_printf(m, "CATMP_STEADY_TTJ_DELTA %d\n", CATMP_STEADY_TTJ_DELTA);
  1195. /* --- cATM+ parameters --- */
  1196. return 0;
  1197. }
  1198. static ssize_t tscpu_write_ctm(struct file *file, const char __user *buffer, size_t count,
  1199. loff_t *data)
  1200. {
  1201. char desc[256];
  1202. int len = 0;
  1203. int t_ctm_on = -1, t_MAX_TARGET_TJ = -1, t_STEADY_TARGET_TJ = -1, t_TRIP_TPCB =
  1204. -1, t_STEADY_TARGET_TPCB = -1, t_MAX_EXIT_TJ = -1, t_STEADY_EXIT_TJ = -1, t_COEF_AE =
  1205. -1, t_COEF_BE = -1, t_COEF_AX = -1, t_COEF_BX = -1,
  1206. t_K_SUM_TT_HIGH = -1, t_K_SUM_TT_LOW = -1, t_CATMP_STEADY_TTJ_DELTA = -1;
  1207. len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
  1208. if (copy_from_user(desc, buffer, len))
  1209. return 0;
  1210. desc[len] = '\0';
  1211. if (11 <= sscanf(desc, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d", &t_ctm_on, &t_MAX_TARGET_TJ,
  1212. &t_STEADY_TARGET_TJ, &t_TRIP_TPCB, &t_STEADY_TARGET_TPCB, &t_MAX_EXIT_TJ,
  1213. &t_STEADY_EXIT_TJ, &t_COEF_AE, &t_COEF_BE, &t_COEF_AX, &t_COEF_BX,
  1214. &t_K_SUM_TT_HIGH, &t_K_SUM_TT_LOW, &t_CATMP_STEADY_TTJ_DELTA)) {
  1215. tscpu_printk("%s input %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", __func__, t_ctm_on,
  1216. t_MAX_TARGET_TJ, t_STEADY_TARGET_TJ, t_TRIP_TPCB, t_STEADY_TARGET_TPCB,
  1217. t_MAX_EXIT_TJ, t_STEADY_EXIT_TJ, t_COEF_AE, t_COEF_BE, t_COEF_AX,
  1218. t_COEF_BX, t_K_SUM_TT_HIGH, t_K_SUM_TT_LOW, t_CATMP_STEADY_TTJ_DELTA);
  1219. if (t_ctm_on < 0 || t_ctm_on > 2)
  1220. #ifdef CONFIG_MTK_AEE_FEATURE
  1221. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  1222. "tscpu_write_ctm", "Wrong thermal policy");
  1223. #endif
  1224. if (t_MAX_TARGET_TJ < -20000 || t_MAX_TARGET_TJ > 200000)
  1225. #ifdef CONFIG_MTK_AEE_FEATURE
  1226. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  1227. "tscpu_write_ctm", "Wrong thermal policy");
  1228. #endif
  1229. if (t_STEADY_TARGET_TJ < -20000 || t_STEADY_TARGET_TJ > 200000)
  1230. #ifdef CONFIG_MTK_AEE_FEATURE
  1231. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  1232. "tscpu_write_ctm", "Wrong thermal policy");
  1233. #endif
  1234. if (t_TRIP_TPCB < -20000 || t_TRIP_TPCB > 200000)
  1235. #ifdef CONFIG_MTK_AEE_FEATURE
  1236. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  1237. "tscpu_write_ctm", "Wrong thermal policy");
  1238. #endif
  1239. if (t_STEADY_TARGET_TPCB < -20000 || t_STEADY_TARGET_TPCB > 200000)
  1240. #ifdef CONFIG_MTK_AEE_FEATURE
  1241. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  1242. "tscpu_write_ctm", "Wrong thermal policy");
  1243. #endif
  1244. if (t_MAX_EXIT_TJ < -20000 || t_MAX_EXIT_TJ > 200000)
  1245. #ifdef CONFIG_MTK_AEE_FEATURE
  1246. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  1247. "tscpu_write_ctm", "Wrong thermal policy");
  1248. #endif
  1249. if (t_STEADY_EXIT_TJ < -20000 || t_STEADY_EXIT_TJ > 200000)
  1250. #ifdef CONFIG_MTK_AEE_FEATURE
  1251. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  1252. "tscpu_write_ctm", "Wrong thermal policy");
  1253. #endif
  1254. if (t_COEF_AE < 0 || t_COEF_BE < 0 || t_COEF_AX < 0 || t_COEF_BX < 0)
  1255. #ifdef CONFIG_MTK_AEE_FEATURE
  1256. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT,
  1257. "tscpu_write_ctm", "Wrong thermal policy");
  1258. #endif
  1259. /* no parameter checking here */
  1260. ctm_on = t_ctm_on; /* 2: cATM+, 1: cATMv1, 0: off */
  1261. MAX_TARGET_TJ = t_MAX_TARGET_TJ;
  1262. STEADY_TARGET_TJ = t_STEADY_TARGET_TJ;
  1263. TRIP_TPCB = t_TRIP_TPCB;
  1264. STEADY_TARGET_TPCB = t_STEADY_TARGET_TPCB;
  1265. MAX_EXIT_TJ = t_MAX_EXIT_TJ;
  1266. STEADY_EXIT_TJ = t_STEADY_EXIT_TJ;
  1267. COEF_AE = t_COEF_AE;
  1268. COEF_BE = t_COEF_BE;
  1269. COEF_AX = t_COEF_AX;
  1270. COEF_BX = t_COEF_BX;
  1271. /* +++ cATM+ parameters +++ */
  1272. if (ctm_on == 2) {
  1273. if (t_K_SUM_TT_HIGH >= 0 && t_K_SUM_TT_HIGH < MAX_K_SUM_TT)
  1274. K_SUM_TT_HIGH = t_K_SUM_TT_HIGH;
  1275. if (t_K_SUM_TT_LOW >= 0 && t_K_SUM_TT_LOW < MAX_K_SUM_TT)
  1276. K_SUM_TT_LOW = t_K_SUM_TT_LOW;
  1277. if (t_CATMP_STEADY_TTJ_DELTA >= 0)
  1278. CATMP_STEADY_TTJ_DELTA = t_CATMP_STEADY_TTJ_DELTA;
  1279. catmplus_update_params();
  1280. }
  1281. /* --- cATM+ parameters --- */
  1282. return count;
  1283. }
  1284. tscpu_dprintk("%s bad argument\n", __func__);
  1285. return -EINVAL;
  1286. }
  1287. #endif
  1288. #if PRECISE_HYBRID_POWER_BUDGET
  1289. static int tscpu_read_phpb(struct seq_file *m, void *v)
  1290. {
  1291. int i;
  1292. struct phpb_param *p;
  1293. for (i = 0; i < NR_PHPB_PARAMS; i++) {
  1294. p = &phpb_params[i];
  1295. seq_printf(m, "[%s] %d %d\n", p->type, p->tt, p->tp);
  1296. }
  1297. seq_printf(m, "[common] %d %d\n", tj_jump_threshold, phpb_theta_max);
  1298. return 0;
  1299. }
  1300. static ssize_t tscpu_write_phpb(struct file *file, const char __user *buffer,
  1301. size_t count, loff_t *data)
  1302. {
  1303. char *buf, *ori_buf;
  1304. int i, tt, tp;
  1305. int __tj_jump_threshold, __theta;
  1306. int ret = -EINVAL;
  1307. struct phpb_param *p;
  1308. buf = kmalloc(count + 1, GFP_KERNEL);
  1309. if (buf == NULL)
  1310. return -EFAULT;
  1311. ori_buf = buf;
  1312. if (copy_from_user(buf, buffer, count)) {
  1313. ret = -EFAULT;
  1314. goto exit;
  1315. }
  1316. buf[count] = '\0';
  1317. for (i = 0; i < NR_PHPB_PARAMS; i++) {
  1318. p = &phpb_params[i];
  1319. if (strstr(buf, p->type))
  1320. break;
  1321. }
  1322. if (i < NR_PHPB_PARAMS) {
  1323. strsep(&buf, " ");
  1324. if (sscanf(buf, "%d %d", &tt, &tp) != 2)
  1325. goto exit;
  1326. /* TODO verify values */
  1327. p->tt = tt;
  1328. p->tp = tp;
  1329. } else {
  1330. if (strstr(buf, "common") == NULL)
  1331. goto exit;
  1332. strsep(&buf, " ");
  1333. if (sscanf(buf, "%d %d", &__tj_jump_threshold, &__theta) != 2)
  1334. goto exit;
  1335. if (__tj_jump_threshold < tj_stable_range)
  1336. goto exit;
  1337. tj_jump_threshold = __tj_jump_threshold;
  1338. if (__theta < phpb_theta_min)
  1339. goto exit;
  1340. phpb_theta_max = __theta;
  1341. }
  1342. ret = count;
  1343. exit:
  1344. kfree(ori_buf);
  1345. return ret;
  1346. }
  1347. static void phpb_params_init(void)
  1348. {
  1349. phpb_params[PHPB_PARAM_CPU].tt = 40;
  1350. phpb_params[PHPB_PARAM_CPU].tp = 40;
  1351. strncpy(phpb_params[PHPB_PARAM_CPU].type, "cpu", strlen("cpu"));
  1352. phpb_params[PHPB_PARAM_GPU].tt = 80;
  1353. phpb_params[PHPB_PARAM_GPU].tp = 80;
  1354. strncpy(phpb_params[PHPB_PARAM_GPU].type, "gpu", strlen("gpu"));
  1355. }
  1356. #endif
  1357. #endif
  1358. #if CPT_ADAPTIVE_AP_COOLER
  1359. static int tscpu_atm_setting_open(struct inode *inode, struct file *file)
  1360. {
  1361. return single_open(file, tscpu_read_atm_setting, NULL);
  1362. }
  1363. static const struct file_operations mtktscpu_atm_setting_fops = {
  1364. .owner = THIS_MODULE,
  1365. .open = tscpu_atm_setting_open,
  1366. .read = seq_read,
  1367. .llseek = seq_lseek,
  1368. .write = tscpu_write_atm_setting,
  1369. .release = single_release,
  1370. };
  1371. static int tscpu_gpu_threshold_open(struct inode *inode, struct file *file)
  1372. {
  1373. return single_open(file, tscpu_read_gpu_threshold, NULL);
  1374. }
  1375. static const struct file_operations mtktscpu_gpu_threshold_fops = {
  1376. .owner = THIS_MODULE,
  1377. .open = tscpu_gpu_threshold_open,
  1378. .read = seq_read,
  1379. .llseek = seq_lseek,
  1380. .write = tscpu_write_gpu_threshold,
  1381. .release = single_release,
  1382. };
  1383. /* +ASC+ */
  1384. static int tscpu_open_atm(struct inode *inode, struct file *file)
  1385. {
  1386. return single_open(file, tscpu_read_atm, NULL);
  1387. }
  1388. static const struct file_operations mtktscpu_atm_fops = {
  1389. .owner = THIS_MODULE,
  1390. .open = tscpu_open_atm,
  1391. .read = seq_read,
  1392. .llseek = seq_lseek,
  1393. .write = tscpu_write_atm,
  1394. .release = single_release,
  1395. };
  1396. /* -ASC- */
  1397. #if THERMAL_HEADROOM
  1398. static int tscpu_thp_open(struct inode *inode, struct file *file)
  1399. {
  1400. return single_open(file, tscpu_read_thp, NULL);
  1401. }
  1402. static const struct file_operations mtktscpu_thp_fops = {
  1403. .owner = THIS_MODULE,
  1404. .open = tscpu_thp_open,
  1405. .read = seq_read,
  1406. .llseek = seq_lseek,
  1407. .write = tscpu_write_thp,
  1408. .release = single_release,
  1409. };
  1410. #endif
  1411. #if CONTINUOUS_TM
  1412. static int tscpu_ctm_open(struct inode *inode, struct file *file)
  1413. {
  1414. return single_open(file, tscpu_read_ctm, NULL);
  1415. }
  1416. static const struct file_operations mtktscpu_ctm_fops = {
  1417. .owner = THIS_MODULE,
  1418. .open = tscpu_ctm_open,
  1419. .read = seq_read,
  1420. .llseek = seq_lseek,
  1421. .write = tscpu_write_ctm,
  1422. .release = single_release,
  1423. };
  1424. #endif /* CONTINUOUS_TM */
  1425. #if PRECISE_HYBRID_POWER_BUDGET
  1426. static int tscpu_phpb_open(struct inode *inode, struct file *file)
  1427. {
  1428. return single_open(file, tscpu_read_phpb, NULL);
  1429. }
  1430. static const struct file_operations mtktscpu_phpb_fops = {
  1431. .owner = THIS_MODULE,
  1432. .open = tscpu_phpb_open,
  1433. .read = seq_read,
  1434. .llseek = seq_lseek,
  1435. .write = tscpu_write_phpb,
  1436. .release = single_release,
  1437. };
  1438. #endif
  1439. #endif /* CPT_ADAPTIVE_AP_COOLER */
  1440. #if PRECISE_HYBRID_POWER_BUDGET
  1441. static void phpb_init(struct proc_dir_entry *mtktscpu_dir)
  1442. {
  1443. struct proc_dir_entry *entry;
  1444. phpb_params_init();
  1445. entry = proc_create("clphpb", S_IRUGO | S_IWUSR, mtktscpu_dir, &mtktscpu_phpb_fops);
  1446. if (entry)
  1447. proc_set_user(entry, uid, gid);
  1448. }
  1449. #endif
  1450. static void tscpu_cooler_create_fs(void)
  1451. {
  1452. struct proc_dir_entry *entry = NULL;
  1453. struct proc_dir_entry *mtktscpu_dir = NULL;
  1454. mtktscpu_dir = mtk_thermal_get_proc_drv_therm_dir_entry();
  1455. if (!mtktscpu_dir) {
  1456. tscpu_printk("[%s]: mkdir /proc/driver/thermal failed\n", __func__);
  1457. } else {
  1458. #if CPT_ADAPTIVE_AP_COOLER
  1459. entry =
  1460. proc_create("clatm_setting", S_IRUGO | S_IWUSR | S_IWGRP, mtktscpu_dir,
  1461. &mtktscpu_atm_setting_fops);
  1462. if (entry)
  1463. proc_set_user(entry, uid, gid);
  1464. entry =
  1465. proc_create("clatm_gpu_threshold", S_IRUGO | S_IWUSR | S_IWGRP, mtktscpu_dir,
  1466. &mtktscpu_gpu_threshold_fops);
  1467. if (entry)
  1468. proc_set_user(entry, uid, gid);
  1469. #endif /* #if CPT_ADAPTIVE_AP_COOLER */
  1470. /* +ASC+ */
  1471. entry = proc_create("clatm", S_IRUGO | S_IWUSR, mtktscpu_dir, &mtktscpu_atm_fops);
  1472. if (entry)
  1473. proc_set_user(entry, uid, gid);
  1474. /* -ASC- */
  1475. #if THERMAL_HEADROOM
  1476. entry = proc_create("clthp", S_IRUGO | S_IWUSR, mtktscpu_dir, &mtktscpu_thp_fops);
  1477. if (entry)
  1478. proc_set_user(entry, uid, gid);
  1479. #endif
  1480. #if CONTINUOUS_TM
  1481. entry = proc_create("clctm", S_IRUGO | S_IWUSR, mtktscpu_dir, &mtktscpu_ctm_fops);
  1482. if (entry)
  1483. proc_set_user(entry, uid, gid);
  1484. #endif
  1485. #if PRECISE_HYBRID_POWER_BUDGET
  1486. phpb_init(mtktscpu_dir);
  1487. #endif
  1488. }
  1489. }
  1490. static int __init mtk_cooler_atm_init(void)
  1491. {
  1492. int err = 0;
  1493. tscpu_dprintk("mtk_cooler_atm_init: Start\n");
  1494. #if CPT_ADAPTIVE_AP_COOLER
  1495. _adaptive_power_calc = _adaptive_power; /* default use old version */
  1496. cl_dev_adp_cpu[0] = mtk_thermal_cooling_device_register("cpu_adaptive_0", NULL,
  1497. &mtktscpu_cooler_adp_cpu_ops);
  1498. cl_dev_adp_cpu[1] = mtk_thermal_cooling_device_register("cpu_adaptive_1", NULL,
  1499. &mtktscpu_cooler_adp_cpu_ops);
  1500. cl_dev_adp_cpu[2] = mtk_thermal_cooling_device_register("cpu_adaptive_2", NULL,
  1501. &mtktscpu_cooler_adp_cpu_ops);
  1502. #endif
  1503. if (err) {
  1504. tscpu_printk("tscpu_register_DVFS_hotplug_cooler fail\n");
  1505. return err;
  1506. }
  1507. tscpu_cooler_create_fs();
  1508. #if 0
  1509. reset_gpu_power_history();
  1510. #endif
  1511. tscpu_dprintk("mtk_cooler_atm_init: End\n");
  1512. return 0;
  1513. }
  1514. static void __exit mtk_cooler_atm_exit(void)
  1515. {
  1516. #if CPT_ADAPTIVE_AP_COOLER
  1517. if (cl_dev_adp_cpu[0]) {
  1518. mtk_thermal_cooling_device_unregister(cl_dev_adp_cpu[0]);
  1519. cl_dev_adp_cpu[0] = NULL;
  1520. }
  1521. if (cl_dev_adp_cpu[1]) {
  1522. mtk_thermal_cooling_device_unregister(cl_dev_adp_cpu[1]);
  1523. cl_dev_adp_cpu[1] = NULL;
  1524. }
  1525. if (cl_dev_adp_cpu[2]) {
  1526. mtk_thermal_cooling_device_unregister(cl_dev_adp_cpu[2]);
  1527. cl_dev_adp_cpu[2] = NULL;
  1528. }
  1529. #endif
  1530. }
  1531. module_init(mtk_cooler_atm_init);
  1532. module_exit(mtk_cooler_atm_exit);