| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417 |
- /*
- * Copyright (C) 2015 MediaTek Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
- #define DEBUG 1
- #include <linux/version.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/dmi.h>
- #include <linux/acpi.h>
- #include <linux/thermal.h>
- #include <linux/platform_device.h>
- #include <mt-plat/aee.h>
- #include <linux/types.h>
- #include <linux/delay.h>
- #include <linux/proc_fs.h>
- #include <linux/spinlock.h>
- #include <mt-plat/sync_write.h>
- #include "mt-plat/mtk_thermal_monitor.h"
- #include <linux/seq_file.h>
- #include <linux/slab.h>
- #include "mtk_thermal_typedefs.h"
- #include "mach/mt_thermal.h"
- #if defined(CONFIG_MTK_CLKMGR)
- #include <mach/mt_clkmgr.h>
- #else
- #include <linux/clk.h>
- #endif
- #include <mt_ptp.h>
- /* #include <mach/mt_wtd.h> */
- #include <mach/wd_api.h>
- #include <mtk_gpu_utility.h>
- #include <linux/time.h>
- #include <tscpu_settings.h>
- #ifdef CONFIG_OF
- #include <linux/of.h>
- #include <linux/of_irq.h>
- #include <linux/of_address.h>
- #endif
- #define __MT_MTK_TS_CPU_C__
- #if MTK_TS_CPU_RT
- #include <linux/sched.h>
- #include <linux/kthread.h>
- #endif
- #if defined(CONFIG_ARCH_MT6755)
- #include "mach/mt_ppm_api.h"
- #else
- #include "mt_cpufreq.h"
- #endif
- #include <linux/uidgid.h>
- #include "mt_auxadc.h"
- /*=============================================================
- *Local variable definition
- *=============================================================*/
- static kuid_t uid = KUIDT_INIT(0);
- static kgid_t gid = KGIDT_INIT(1000);
- #if !defined(CONFIG_MTK_CLKMGR)
- struct clk *therm_main; /* main clock for Thermal */
- #if defined(CONFIG_ARCH_MT6755)
- /*Patch to pause thermal controller and turn off auxadc GC.
- For mt6755 only*/
- struct clk *therm_auxadc;
- #endif
- #endif
- void __iomem *therm_clk_infracfg_ao_base;
- #ifdef CONFIG_OF
- u32 thermal_irq_number = 0;
- void __iomem *thermal_base;
- void __iomem *auxadc_ts_base;
- void __iomem *infracfg_ao_base;
- #if defined(CONFIG_ARCH_MT6755)
- void __iomem *th_apmixed_base;
- #else
- void __iomem *apmixed_base;
- #endif
- void __iomem *INFRACFG_AO_base;
- int thermal_phy_base;
- int auxadc_ts_phy_base;
- int apmixed_phy_base;
- int pericfg_phy_base;
- #endif
- static unsigned int interval = 1000; /* mseconds, 0 : no auto polling */
- int tscpu_g_curr_temp = 0;
- int tscpu_g_prev_temp = 0;
- static int g_max_temp = 50000; /* default=50 deg */
- #if defined(CONFIG_ARCH_MT6753)
- /*For MT6753 PMIC 5A throttle patch*/
- static int thermal5A_TH = 55000;
- static int thermal5A_status;
- #endif
- static int tc_mid_trip = -275000;
- /* trip_temp[0] must be initialized to the thermal HW protection point. */
- #if !defined(CONFIG_ARCH_MT6755)
- static int trip_temp[10] = { 117000, 100000, 85000, 75000, 65000, 55000, 45000, 35000, 25000, 15000 };
- #else
- static int trip_temp[10] = { 117000, 90000, 85000, 75000, 65000, 55000, 45000, 35000, 25000, 15000 };
- #endif
- int tscpu_read_curr_temp;
- static bool talking_flag;
- static int kernelmode;
- static int g_THERMAL_TRIP[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- static int temperature_switch;
- static int num_trip = 5;
- static int tscpu_num_opp;
- static struct mtk_cpu_power_info *mtk_cpu_power;
- static int g_tc_resume; /* default=0,read temp */
- static int MA_len_temp;
- static int proc_write_flag;
- static struct thermal_zone_device *thz_dev;
- static char g_bind0[20] = "mtktscpu-sysrst";
- #if !defined(CONFIG_ARCH_MT6755)
- static char g_bind1[20] = "cpu02";
- static char g_bind2[20] = "cpu15";
- static char g_bind3[20] = "cpu22";
- static char g_bind4[20] = "cpu28";
- #else
- static char g_bind1[20] = "cpu00";
- static char g_bind2[20] = "cpu00";
- static char g_bind3[20] = "cpu03";
- static char g_bind4[20] = "cpu04";
- #endif
- static char g_bind5[20] = "";
- static char g_bind6[20] = "";
- static char g_bind7[20] = "";
- static char g_bind8[20] = "";
- static char g_bind9[20] = "";
- struct mt_gpufreq_power_table_info *mtk_gpu_power = NULL;
- #if 0
- int Num_of_GPU_OPP = 1; /* Set this value =1 for non-DVS GPU */
- #else /* DVFS GPU */
- int Num_of_GPU_OPP = 0;
- #endif
- /*=============================================================
- * Local function definition
- *=============================================================*/
- #if (CONFIG_THERMAL_AEE_RR_REC == 1)
- static void _mt_thermal_aee_init(void)
- {
- aee_rr_rec_thermal_temp1(0xFF);
- aee_rr_rec_thermal_temp2(0xFF);
- aee_rr_rec_thermal_temp3(0xFF);
- aee_rr_rec_thermal_temp4(0xFF);
- aee_rr_rec_thermal_temp5(0xFF);
- aee_rr_rec_thermal_status(0xFF);
- }
- #endif
- static int tscpu_thermal_probe(struct platform_device *dev);
- static int tscpu_register_thermal(void);
- static void tscpu_unregister_thermal(void);
- #if THERMAL_DRV_UPDATE_TEMP_DIRECT_TO_MET
- static int a_tscpu_all_temp[MTK_THERMAL_SENSOR_CPU_COUNT] = { 0 };
- static DEFINE_MUTEX(MET_GET_TEMP_LOCK);
- static met_thermalsampler_funcMET g_pThermalSampler;
- void mt_thermalsampler_registerCB(met_thermalsampler_funcMET pCB)
- {
- g_pThermalSampler = pCB;
- }
- EXPORT_SYMBOL(mt_thermalsampler_registerCB);
- static DEFINE_SPINLOCK(tscpu_met_spinlock);
- void tscpu_met_lock(unsigned long *flags)
- {
- spin_lock_irqsave(&tscpu_met_spinlock, *flags);
- }
- EXPORT_SYMBOL(tscpu_met_lock);
- void tscpu_met_unlock(unsigned long *flags)
- {
- spin_unlock_irqrestore(&tscpu_met_spinlock, *flags);
- }
- EXPORT_SYMBOL(tscpu_met_unlock);
- #endif
- static int g_is_temp_valid;
- static void temp_valid_lock(unsigned long *flags);
- static void temp_valid_unlock(unsigned long *flags);
- /*=============================================================
- *Weak functions
- *=============================================================*/
- int __attribute__ ((weak))
- IMM_IsAdcInitReady(void)
- {
- pr_err("E_WF: %s doesn't exist\n", __func__);
- return 0;
- }
- #if defined(CONFIG_ARCH_MT6755)
- void __attribute__ ((weak))
- mt_ppm_cpu_thermal_protect(unsigned int limited_power)
- {
- pr_err("E_WF: %s doesn't exist\n", __func__);
- }
- #else
- void __attribute__ ((weak))
- mt_cpufreq_thermal_protect(unsigned int limited_power)
- {
- pr_err("E_WF: %s doesn't exist\n", __func__);
- }
- #endif
- bool __attribute__ ((weak))
- mtk_get_gpu_loading(unsigned int *pLoading)
- {
- pr_err("E_WF: %s doesn't exist\n", __func__);
- return 0;
- }
- void __attribute__ ((weak))
- mt_ptp_lock(unsigned long *flags)
- {
- pr_err("E_WF: %s doesn't exist\n", __func__);
- }
- void __attribute__ ((weak))
- mt_ptp_unlock(unsigned long *flags)
- {
- pr_err("E_WF: %s doesn't exist\n", __func__);
- }
- int __attribute__ ((weak))
- get_immediate_ts1_wrap(void)
- {
- return 0;
- }
- int __attribute__ ((weak))
- get_immediate_ts2_wrap(void)
- {
- return 0;
- }
- int __attribute__ ((weak))
- get_immediate_ts3_wrap(void)
- {
- return 0;
- }
- int __attribute__ ((weak))
- get_immediate_ts4_wrap(void)
- {
- return 0;
- }
- int __attribute__ ((weak))
- get_immediate_tsabb_wrap(void)
- {
- return 0;
- }
- void __attribute__ ((weak))
- mt_cpufreq_thermal_5A_limit(bool enable)
- {
- pr_err("E_WF: %s doesn't exist\n", __func__);
- }
- /*=============================================================*/
- static void tscpu_fast_initial_sw_workaround(void)
- {
- int i = 0;
- unsigned long flags;
- /* tscpu_printk("tscpu_fast_initial_sw_workaround\n"); */
- /* tscpu_thermal_clock_on(); */
- mt_ptp_lock(&flags);
- for (i = 0; i < TS_LEN_ARRAY(tscpu_g_bank); i++) {
- tscpu_switch_bank(i);
- tscpu_thermal_fast_init();
- }
- mt_ptp_unlock(&flags);
- temp_valid_lock(&flags);
- g_is_temp_valid = 0;
- temp_valid_unlock(&flags);
- }
- void tscpu_thermal_tempADCPNP(int adc, int order)
- {
- tscpu_dprintk("%s adc %x, order %d\n", __func__, adc, order);
- switch (order) {
- case 0:
- THERMAL_WRAP_WR32(adc, TEMPADCPNP0);
- break;
- case 1:
- THERMAL_WRAP_WR32(adc, TEMPADCPNP1);
- break;
- case 2:
- THERMAL_WRAP_WR32(adc, TEMPADCPNP2);
- break;
- case 3:
- THERMAL_WRAP_WR32(adc, TEMPADCPNP3);
- break;
- default:
- THERMAL_WRAP_WR32(adc, TEMPADCPNP0);
- break;
- }
- }
- int tscpu_thermal_ADCValueOfMcu(enum thermal_sensor_enum type)
- {
- switch (type) {
- case MCU1:
- return TEMPADC_MCU1;
- case MCU2:
- return TEMPADC_MCU2;
- case MCU3:
- return TEMPADC_MCU3;
- case MCU4:
- return TEMPADC_MCU4;
- case ABB:
- return TEMPADC_ABB;
- default:
- return TEMPADC_MCU1;
- }
- }
- static int max_temperature_in_bank(thermal_bank_name bank)
- {
- int j = 0;
- int max_in_bank = 0;
- for (j = 0; j < tscpu_g_bank[bank].ts_number; j++) {
- if (tscpu_bank_ts[bank][tscpu_g_bank[bank].ts[j].type] > max_in_bank)
- max_in_bank = tscpu_bank_ts[bank][tscpu_g_bank[bank].ts[j].type];
- tscpu_dprintk("tscpu_get_temp CPU bank%d T%d=%d\n", bank, j,
- tscpu_bank_ts[bank][tscpu_g_bank[bank].ts[j].type]);
- }
- return max_in_bank;
- }
- int tscpu_max_temperature(void)
- {
- int i = 0;
- int max = 0;
- int max_in_bank = 0;
- tscpu_dprintk("tscpu_get_temp %s, %d\n", __func__, __LINE__);
- for (i = 0; i < TS_LEN_ARRAY(tscpu_g_bank); i++) {
- max_in_bank = max_temperature_in_bank(i);
- if (max_in_bank > max)
- max = max_in_bank;
- }
- return max;
- }
- void tscpu_print_all_temperature(int isDprint)
- {
- int i = 0, j = 0;
- for (i = 0; i < TS_LEN_ARRAY(tscpu_g_bank); i++) {
- for (j = 0; j < tscpu_g_bank[i].ts_number; j++) {
- if (isDprint)
- tscpu_dprintk("%d ", tscpu_bank_ts[i][tscpu_g_bank[i].ts[j].type]);
- else
- tscpu_printk("%d ", tscpu_bank_ts[i][tscpu_g_bank[i].ts[j].type]);
- }
- }
- if (isDprint)
- tscpu_dprintk("\n");
- else
- tscpu_printk("\n");
- }
- void set_taklking_flag(bool flag)
- {
- talking_flag = flag;
- tscpu_printk("talking_flag=%d\n", talking_flag);
- }
- int mtk_gpufreq_register(struct mt_gpufreq_power_table_info *freqs, int num)
- {
- int i = 0;
- tscpu_dprintk("mtk_gpufreq_register\n");
- mtk_gpu_power = kzalloc((num) * sizeof(struct mt_gpufreq_power_table_info), GFP_KERNEL);
- if (mtk_gpu_power == NULL)
- return -ENOMEM;
- for (i = 0; i < num; i++) {
- mtk_gpu_power[i].gpufreq_khz = freqs[i].gpufreq_khz;
- mtk_gpu_power[i].gpufreq_power = freqs[i].gpufreq_power;
- tscpu_dprintk("[%d].gpufreq_khz=%u, .gpufreq_power=%u\n",
- i, freqs[i].gpufreq_khz, freqs[i].gpufreq_power);
- }
- Num_of_GPU_OPP = num; /* GPU OPP count */
- return 0;
- }
- EXPORT_SYMBOL(mtk_gpufreq_register);
- static int tscpu_bind(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev)
- {
- int table_val = 0;
- if (!strcmp(cdev->type, g_bind0)) {
- table_val = 0;
- tscpu_config_all_tc_hw_protect(trip_temp[0], tc_mid_trip);
- /* tscpu_dprintk("tscpu_bind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind1)) {
- table_val = 1;
- /* only when a valid cooler is tried to bind here, we set tc_mid_trip to trip_temp[1]; */
- tc_mid_trip = trip_temp[1];
- tscpu_config_all_tc_hw_protect(trip_temp[0], tc_mid_trip);
- /* tscpu_dprintk("tscpu_bind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind2)) {
- table_val = 2;
- /* tscpu_dprintk("tscpu_bind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind3)) {
- table_val = 3;
- /* tscpu_dprintk("tscpu_bind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind4)) {
- table_val = 4;
- /* tscpu_dprintk("tscpu_bind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind5)) {
- table_val = 5;
- /* tscpu_dprintk("tscpu_bind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind6)) {
- table_val = 6;
- /* tscpu_dprintk("tscpu_bind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind7)) {
- table_val = 7;
- /* tscpu_dprintk("tscpu_bind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind8)) {
- table_val = 8;
- /* tscpu_dprintk("tscpu_bind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind9)) {
- table_val = 9;
- /* tscpu_dprintk("tscpu_bind %s\n", cdev->type); */
- } else {
- return 0;
- }
- if (mtk_thermal_zone_bind_cooling_device(thermal, table_val, cdev)) {
- tscpu_warn("tscpu_bind error binding cooling dev\n");
- return -EINVAL;
- }
- tscpu_printk("tscpu_bind binding OK, %d\n", table_val);
- return 0;
- }
- static int tscpu_unbind(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev)
- {
- int table_val = 0;
- if (!strcmp(cdev->type, g_bind0)) {
- table_val = 0;
- /* tscpu_dprintk("tscpu_unbind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind1)) {
- table_val = 1;
- /* only when a valid cooler is tried to bind here, we set tc_mid_trip to trip_temp[1]; */
- tc_mid_trip = -275000;
- /* tscpu_dprintk("tscpu_unbind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind2)) {
- table_val = 2;
- /* tscpu_dprintk("tscpu_unbind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind3)) {
- table_val = 3;
- /* tscpu_dprintk("tscpu_unbind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind4)) {
- table_val = 4;
- /* tscpu_dprintk("tscpu_unbind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind5)) {
- table_val = 5;
- /* tscpu_dprintk("tscpu_unbind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind6)) {
- table_val = 6;
- /* tscpu_dprintk("tscpu_unbind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind7)) {
- table_val = 7;
- /* tscpu_dprintk("tscpu_unbind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind8)) {
- table_val = 8;
- /* tscpu_dprintk("tscpu_unbind %s\n", cdev->type); */
- } else if (!strcmp(cdev->type, g_bind9)) {
- table_val = 9;
- /* tscpu_dprintk("tscpu_unbind %s\n", cdev->type); */
- } else
- return 0;
- if (thermal_zone_unbind_cooling_device(thermal, table_val, cdev)) {
- tscpu_warn("tscpu_unbind error unbinding cooling dev\n");
- return -EINVAL;
- }
- tscpu_printk("tscpu_unbind unbinding OK\n");
- return 0;
- }
- static int tscpu_get_mode(struct thermal_zone_device *thermal, enum thermal_device_mode *mode)
- {
- *mode = (kernelmode) ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED;
- return 0;
- }
- static int tscpu_set_mode(struct thermal_zone_device *thermal, enum thermal_device_mode mode)
- {
- kernelmode = mode;
- return 0;
- }
- static int tscpu_get_trip_type(struct thermal_zone_device *thermal, int trip,
- enum thermal_trip_type *type)
- {
- *type = g_THERMAL_TRIP[trip];
- return 0;
- }
- static int tscpu_get_trip_temp(struct thermal_zone_device *thermal, int trip, unsigned long *temp)
- {
- *temp = trip_temp[trip];
- return 0;
- }
- static int tscpu_get_crit_temp(struct thermal_zone_device *thermal, unsigned long *temperature)
- {
- *temperature = MTKTSCPU_TEMP_CRIT;
- return 0;
- }
- static int tscpu_get_temp(struct thermal_zone_device *thermal, unsigned long *t)
- {
- int ret = 0;
- int curr_temp;
- int temp_temp;
- static int last_cpu_real_temp;
- curr_temp = tscpu_get_curr_temp();
- tscpu_dprintk("tscpu_get_temp CPU Max T=%d\n", curr_temp);
- if ((curr_temp > (trip_temp[0] - 15000)) || (curr_temp < -30000) || (curr_temp > 85000)) {
- printk_ratelimited("%d %d CPU T=%d\n",
- get_adaptive_power_limit(0), get_adaptive_power_limit(1), curr_temp);
- }
- temp_temp = curr_temp;
- if (curr_temp != 0) {/* not resumed from suspensio... */
- if ((curr_temp > 150000) || (curr_temp < -20000)) { /* invalid range */
- tscpu_warn("CPU temp invalid=%d\n", curr_temp);
- temp_temp = 50000;
- ret = -1;
- } else if (last_cpu_real_temp != 0) {
- if ((curr_temp - last_cpu_real_temp > 40000) || (last_cpu_real_temp - curr_temp > 40000)) {
- /* delta 40C, invalid change */
- tscpu_warn("CPU temp float hugely temp=%d, lasttemp=%d\n",
- curr_temp, last_cpu_real_temp);
- /* tscpu_printk("RAW_TS2 = %d,RAW_TS3 = %d,RAW_TS4 = %d\n",RAW_TS2,RAW_TS3,RAW_TS4); */
- temp_temp = 50000;
- ret = -1;
- }
- }
- }
- last_cpu_real_temp = curr_temp;
- curr_temp = temp_temp;
- tscpu_read_curr_temp = curr_temp;
- *t = (unsigned long)curr_temp;
- #if MTKTSCPU_FAST_POLLING
- tscpu_cur_fp_factor = tscpu_next_fp_factor;
- if (curr_temp >= fast_polling_trip_temp) {
- tscpu_next_fp_factor = fast_polling_factor;
- /* it means next timeout will be in interval/fast_polling_factor */
- thermal->polling_delay = interval / fast_polling_factor;
- } else {
- tscpu_next_fp_factor = 1;
- thermal->polling_delay = interval;
- }
- #endif
- /* for low power */
- if ((int)*t >= tscpu_polling_trip_temp1)
- ;
- else if ((int)*t < tscpu_polling_trip_temp2)
- thermal->polling_delay = interval * tscpu_polling_factor2;
- else
- thermal->polling_delay = interval * tscpu_polling_factor1;
- /* tscpu_dprintk("tscpu_get_temp:thermal->polling_delay=%d\n",thermal->polling_delay); */
- #if CPT_ADAPTIVE_AP_COOLER
- tscpu_g_prev_temp = tscpu_g_curr_temp;
- tscpu_g_curr_temp = curr_temp;
- #endif
- #if THERMAL_GPIO_OUT_TOGGLE
- /*for output signal monitor */
- tscpu_set_GPIO_toggle_for_monitor();
- #endif
- #if defined(CONFIG_ARCH_MT6753)
- /*For MT6753 PMIC 5A throttle patch*/
- if (curr_temp >= thermal5A_TH && thermal5A_status == 0) {
- mt_cpufreq_thermal_5A_limit(1);
- thermal5A_status = 1;
- } else if (curr_temp < thermal5A_TH && thermal5A_status == 1) {
- mt_cpufreq_thermal_5A_limit(0);
- thermal5A_status = 0;
- }
- #endif
- g_max_temp = curr_temp;
- return ret;
- }
- /* bind callback functions to thermalzone */
- static struct thermal_zone_device_ops mtktscpu_dev_ops = {
- .bind = tscpu_bind,
- .unbind = tscpu_unbind,
- .get_temp = tscpu_get_temp,
- .get_mode = tscpu_get_mode,
- .set_mode = tscpu_set_mode,
- .get_trip_type = tscpu_get_trip_type,
- .get_trip_temp = tscpu_get_trip_temp,
- .get_crit_temp = tscpu_get_crit_temp,
- };
- static int tscpu_read_Tj_out(struct seq_file *m, void *v)
- {
- int ts_con0 = 0;
- /* TS_CON0[19:16] = 0x8: Tj sensor Analog signal output via HW pin */
- ts_con0 = DRV_Reg32(TS_CON0_TM);
- seq_printf(m, "TS_CON0:0x%x\n", ts_con0);
- return 0;
- }
- static ssize_t tscpu_write_Tj_out(struct file *file, const char __user *buffer, size_t count,
- loff_t *data)
- {
- char desc[32];
- int lv_Tj_out_flag;
- int len = 0;
- len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
- if (copy_from_user(desc, buffer, len))
- return 0;
- desc[len] = '\0';
- if (kstrtoint(desc, 10, &lv_Tj_out_flag) == 0) {
- if (lv_Tj_out_flag == 1) {
- /* TS_CON0[19:16] = 0x8: Tj sensor Analog signal output via HW pin */
- THERMAL_WRAP_WR32(DRV_Reg32(TS_CON0_TM) | 0x00010000, TS_CON0_TM);
- } else {
- /* TS_CON0[19:16] = 0x8: Tj sensor Analog signal output via HW pin */
- THERMAL_WRAP_WR32(DRV_Reg32(TS_CON0_TM) & 0xfffeffff, TS_CON0_TM);
- }
- tscpu_dprintk("tscpu_write_Tj_out lv_Tj_out_flag=%d\n", lv_Tj_out_flag);
- return count;
- }
- tscpu_dprintk("tscpu_write_Tj_out bad argument\n");
- return -EINVAL;
- }
- #if THERMAL_GPIO_OUT_TOGGLE
- static int g_trigger_temp = 95000; /* default 95 deg */
- static int g_GPIO_out_enable; /* 0:disable */
- static int g_GPIO_already_set;
- #define GPIO118_MODE (GPIO_BASE + 0x0770)
- #define GPIO118_DIR (GPIO_BASE + 0x0070)
- #define GPIO118_DOUT (GPIO_BASE + 0x0470)
- void tscpu_set_GPIO_toggle_for_monitor(void)
- {
- int lv_GPIO118_MODE, lv_GPIO118_DIR, lv_GPIO118_DOUT;
- tscpu_dprintk("tscpu_set_GPIO_toggle_for_monitor,g_GPIO_out_enable=%d\n",
- g_GPIO_out_enable);
- if (g_GPIO_out_enable == 1) {
- if (g_max_temp > g_trigger_temp) {
- tscpu_printk("g_max_temp %d > g_trigger_temp %d\n", g_max_temp,
- g_trigger_temp);
- g_GPIO_out_enable = 0; /* only can enter once */
- g_GPIO_already_set = 1;
- lv_GPIO118_MODE = thermal_readl(GPIO118_MODE);
- lv_GPIO118_DIR = thermal_readl(GPIO118_DIR);
- lv_GPIO118_DOUT = thermal_readl(GPIO118_DOUT);
- tscpu_printk("tscpu_set_GPIO_toggle_for_monitor:lv_GPIO118_MODE=0x%x,", lv_GPIO118_MODE);
- tscpu_printk("lv_GPIO118_DIR=0x%x,lv_GPIO118_DOUT=0x%x,\n", lv_GPIO118_DIR, lv_GPIO118_DOUT);
- /* thermal_clrl(GPIO118_MODE,0x00000E00);//clear GPIO118_MODE[11:9] */
- /* thermal_setl(GPIO118_DIR, 0x00000040);//set GPIO118_DIR[6]=1 */
- thermal_clrl(GPIO118_DOUT, 0x00000040); /* set GPIO118_DOUT[6]=0 Low */
- udelay(200);
- thermal_setl(GPIO118_DOUT, 0x00000040); /* set GPIO118_DOUT[6]=1 Hiht */
- } else {
- if (g_GPIO_already_set == 1) {
- /* restore */
- g_GPIO_already_set = 0;
- /* thermal_writel(GPIO118_MODE,lv_GPIO118_MODE); */
- /* thermal_writel(GPIO118_DIR, lv_GPIO118_DIR); */
- /* thermal_writel(GPIO118_DOUT,lv_GPIO118_DOUT); */
- thermal_clrl(GPIO118_DOUT, 0x00000040); /* set GPIO118_DOUT[6]=0 Low */
- }
- }
- }
- }
- /*
- For example:
- GPIO_BASE :0x10005000
- GPIO118_MODE = 0 (change to GPIO mode)
- 0x0770 GPIO_MODE24 16 GPIO Mode Control Register 24
- 11 9 GPIO118_MODE RW Public 3'd1 "0: GPIO118 (IO)1: UTXD3 (O)2: URXD3 (I)3: MD_UTXD (O)
- 4: LTE_UTXD (O)5: TDD_TXD (O)6: Reserved7: DBG_MON_A_10_ (IO)" Selects GPIO 118 mode
- GPIO118_DIR =1 (output)
- 0x0070 GPIO_DIR8 16 GPIO Direction Control Register 8
- 6 6 GPIO118_DIR RW Public 1'b0 "0: Input1: Output" GPIO 118 direction control
- GPIO118_DOUT=1/0 (hi or low)
- 0x0470 GPIO_DOUT8 16 GPIO Data Output Register 8
- 6 6 GPIO118_DOUT RW Public 1'b0 "0: Output 01: Output 1" GPIO 118 data output value
- */
- static int tscpu_read_GPIO_out(struct seq_file *m, void *v)
- {
- seq_printf(m, "GPIO out enable:%d, trigger temperature=%d\n", g_GPIO_out_enable,
- g_trigger_temp);
- return 0;
- }
- static ssize_t tscpu_write_GPIO_out(struct file *file, const char __user *buffer, size_t count,
- loff_t *data)
- {
- char desc[512];
- char TEMP[10], ENABLE[10];
- unsigned int valTEMP, valENABLE;
- int len = 0;
- int lv_GPIO118_MODE, lv_GPIO118_DIR;
- len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
- if (copy_from_user(desc, buffer, len))
- return 0;
- desc[len] = '\0';
- if (sscanf(desc, "%9s %d %9s %d ", TEMP, &valTEMP, ENABLE, &valENABLE) == 4) {
- /* tscpu_printk("XXXXXXXXX\n"); */
- if (!strcmp(TEMP, "TEMP")) {
- g_trigger_temp = valTEMP;
- tscpu_printk("g_trigger_temp=%d\n", valTEMP);
- } else {
- tscpu_printk("tscpu_write_GPIO_out TEMP bad argument\n");
- return -EINVAL;
- }
- if (!strcmp(ENABLE, "ENABLE")) {
- g_GPIO_out_enable = valENABLE;
- tscpu_printk("g_GPIO_out_enable=%d,g_GPIO_already_set=%d\n", valENABLE,
- g_GPIO_already_set);
- } else {
- tscpu_printk("tscpu_write_GPIO_out ENABLE bad argument\n");
- return -EINVAL;
- }
- lv_GPIO118_MODE = thermal_readl(GPIO118_MODE);
- lv_GPIO118_DIR = thermal_readl(GPIO118_DIR);
- /* clear GPIO118_MODE[11:9],GPIO118_MODE = 0 (change to GPIO mode) */
- thermal_clrl(GPIO118_MODE, 0x00000E00);
- thermal_setl(GPIO118_DIR, 0x00000040); /* set GPIO118_DIR[6]=1,GPIO118_DIR =1 (output) */
- thermal_clrl(GPIO118_DOUT, 0x00000040); /* set GPIO118_DOUT[6]=0 Low */
- return count;
- }
- tscpu_printk("tscpu_write_GPIO_out bad argument\n");
- return -EINVAL;
- }
- #endif
- static int tscpu_read_opp(struct seq_file *m, void *v)
- {
- unsigned int cpu_power, gpu_power;
- unsigned int gpu_loading = 0;
- cpu_power = MIN(adaptive_cpu_power_limit, static_cpu_power_limit);
- gpu_power = MIN(adaptive_gpu_power_limit, static_gpu_power_limit);
- #if CPT_ADAPTIVE_AP_COOLER
- if (!mtk_get_gpu_loading(&gpu_loading))
- gpu_loading = 0;
- seq_printf(m, "%d,%d,%d,%d,%d\n",
- (int)((cpu_power != 0x7FFFFFFF) ? cpu_power : 0),
- (int)((gpu_power != 0x7FFFFFFF) ? gpu_power : 0),
- /* ((NULL == mtk_thermal_get_gpu_loading_fp) ? 0 : mtk_thermal_get_gpu_loading_fp()), */
- (int)gpu_loading, (int)mt_gpufreq_get_cur_freq(), get_target_tj());
- #else
- seq_printf(m, "%d,%d,0,%d\n",
- (int)((cpu_power != 0x7FFFFFFF) ? cpu_power : 0),
- (int)((gpu_power != 0x7FFFFFFF) ? gpu_power : 0),
- (int)mt_gpufreq_get_cur_freq());
- #endif
- return 0;
- }
- static int tscpu_talking_flag_read(struct seq_file *m, void *v)
- {
- seq_printf(m, "%d\n", talking_flag);
- return 0;
- }
- static ssize_t tscpu_talking_flag_write(struct file *file, const char __user *buffer, size_t count,
- loff_t *data)
- {
- char desc[32];
- int lv_talking_flag;
- int len = 0;
- len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
- if (copy_from_user(desc, buffer, len))
- return 0;
- desc[len] = '\0';
- if (kstrtoint(desc, 10, &lv_talking_flag) == 0) {
- talking_flag = lv_talking_flag;
- tscpu_dprintk("tscpu_talking_flag_write talking_flag=%d\n", talking_flag);
- return count;
- }
- tscpu_dprintk("tscpu_talking_flag_write bad argument\n");
- return -EINVAL;
- }
- static int tscpu_set_temperature_read(struct seq_file *m, void *v)
- {
- seq_printf(m, "%d\n", temperature_switch);
- return 0;
- }
- static ssize_t tscpu_set_temperature_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *data)
- {
- char desc[32];
- int lv_tempe_switch;
- int len = 0;
- len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
- if (copy_from_user(desc, buffer, len))
- return 0;
- desc[len] = '\0';
- tscpu_dprintk("tscpu_set_temperature_write\n");
- if (kstrtoint(desc, 10, &lv_tempe_switch) == 0) {
- temperature_switch = lv_tempe_switch;
- tscpu_config_all_tc_hw_protect(temperature_switch, tc_mid_trip);
- tscpu_dprintk("tscpu_set_temperature_write temperature_switch=%d\n",
- temperature_switch);
- return count;
- }
- tscpu_warn("tscpu_set_temperature_write bad argument\n");
- return -EINVAL;
- }
- static int tscpu_read_log(struct seq_file *m, void *v)
- {
- seq_printf(m, "[ tscpu_read_log] log = %d\n", tscpu_debug_log);
- return 0;
- }
- static int tscpu_read_cal(struct seq_file *m, void *v)
- {
- /* seq_printf(m, "mtktscpu cal:\n devinfo index(16)=0x%x, devinfo index(17)=0x%x, devinfo index(18)=0x%x\n", */
- /* get_devinfo_with_index(16), get_devinfo_with_index(17), get_devinfo_with_index(18)); */
- return 0;
- }
- static int tscpu_read(struct seq_file *m, void *v)
- {
- int i;
- seq_printf(m,
- "[tscpu_read]%d\ntrip_0=%d %d %s\ntrip_1=%d %d %s\ntrip_2=%d %d %s\ntrip_3=%d %d %s\ntrip_4=%d %d %s\ntrip_5=%d %d %s\ntrip_6=%d %d %s\ntrip_7=%d %d %s\ntrip_8=%d %d %s\ntrip_9=%d %d %s\ninterval=%d\n",
- num_trip,
- trip_temp[0], g_THERMAL_TRIP[0], g_bind0,
- trip_temp[1], g_THERMAL_TRIP[1], g_bind1,
- trip_temp[2], g_THERMAL_TRIP[2], g_bind2,
- trip_temp[3], g_THERMAL_TRIP[3], g_bind3,
- trip_temp[4], g_THERMAL_TRIP[4], g_bind4,
- trip_temp[5], g_THERMAL_TRIP[5], g_bind5,
- trip_temp[6], g_THERMAL_TRIP[6], g_bind6,
- trip_temp[7], g_THERMAL_TRIP[7], g_bind7,
- trip_temp[8], g_THERMAL_TRIP[8], g_bind8,
- trip_temp[9], g_THERMAL_TRIP[9], g_bind9, interval);
- for (i = 0; i < Num_of_GPU_OPP; i++)
- seq_printf(m, "g %d %d %d\n", i, mtk_gpu_power[i].gpufreq_khz,
- mtk_gpu_power[i].gpufreq_power);
- for (i = 0; i < tscpu_num_opp; i++)
- seq_printf(m, "c %d %d %d %d\n", i, mtk_cpu_power[i].cpufreq_khz,
- mtk_cpu_power[i].cpufreq_ncpu, mtk_cpu_power[i].cpufreq_power);
- for (i = 0; i < CPU_COOLER_NUM; i++)
- seq_printf(m, "d %d %d\n", i, tscpu_cpu_dmips[i]);
- return 0;
- }
- static ssize_t tscpu_write_log(struct file *file, const char __user *buffer, size_t count,
- loff_t *data)
- {
- char desc[32];
- int log_switch;
- int len = 0;
- len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
- if (copy_from_user(desc, buffer, len))
- return 0;
- desc[len] = '\0';
- if (kstrtoint(desc, 10, &log_switch) == 0)
- /* if (5 <= sscanf(desc, "%d %d %d %d %d", &log_switch, &hot, &normal, &low, &lv_offset)) */
- {
- tscpu_debug_log = log_switch;
- return count;
- }
- tscpu_warn("tscpu_write_log bad argument\n");
- return -EINVAL;
- }
- #if MTKTSCPU_FAST_POLLING
- static int tscpu_read_fastpoll(struct seq_file *m, void *v)
- {
- seq_printf(m, "trip %d factor %d\n", fast_polling_trip_temp, fast_polling_factor);
- return 0;
- }
- static ssize_t tscpu_write_fastpoll(struct file *file, const char __user *buffer, size_t count,
- loff_t *data)
- {
- char desc[128];
- int len = 0;
- int trip = -1, factor = -1;
- len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
- if (copy_from_user(desc, buffer, len))
- return 0;
- desc[len] = '\0';
- if (2 <= sscanf(desc, "%d %d", &trip, &factor)) {
- tscpu_printk("tscpu_write_fastpoll input %d %d\n", trip, factor);
- if ((trip >= 0) && (factor > 0)) {
- fast_polling_trip_temp = trip;
- fast_polling_factor = factor;
- tscpu_printk("tscpu_write_fastpoll applied %d %d\n", fast_polling_trip_temp,
- fast_polling_factor);
- } else {
- tscpu_dprintk("tscpu_write_fastpoll out of range\n");
- }
- return count;
- }
- tscpu_dprintk("tscpu_write_fastpoll bad argument\n");
- return -EINVAL;
- }
- #endif
- static ssize_t tscpu_write(struct file *file, const char __user *buffer, size_t count,
- loff_t *data)
- {
- int len = 0;
- int i;
- struct mtktscpu_data {
- int trip[10];
- int t_type[10];
- char bind0[20], bind1[20], bind2[20], bind3[20], bind4[20];
- char bind5[20], bind6[20], bind7[20], bind8[20], bind9[20];
- int time_msec;
- char desc[512];
- };
- struct mtktscpu_data *ptr_mtktscpu_data = kmalloc(sizeof(*ptr_mtktscpu_data), GFP_KERNEL);
- if (ptr_mtktscpu_data == NULL) {
- pr_warn("[%s] kmalloc fail\n\n", __func__);
- return -ENOMEM;
- }
- len = (count < (sizeof(ptr_mtktscpu_data->desc) - 1)) ? count : (sizeof(ptr_mtktscpu_data->desc) - 1);
- if (copy_from_user(ptr_mtktscpu_data->desc, buffer, len)) {
- kfree(ptr_mtktscpu_data);
- return 0;
- }
- ptr_mtktscpu_data->desc[len] = '\0';
- if (sscanf
- (ptr_mtktscpu_data->desc,
- "%d %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d",
- &num_trip,
- &ptr_mtktscpu_data->trip[0], &ptr_mtktscpu_data->t_type[0], ptr_mtktscpu_data->bind0,
- &ptr_mtktscpu_data->trip[1], &ptr_mtktscpu_data->t_type[1], ptr_mtktscpu_data->bind1,
- &ptr_mtktscpu_data->trip[2], &ptr_mtktscpu_data->t_type[2], ptr_mtktscpu_data->bind2,
- &ptr_mtktscpu_data->trip[3], &ptr_mtktscpu_data->t_type[3], ptr_mtktscpu_data->bind3,
- &ptr_mtktscpu_data->trip[4], &ptr_mtktscpu_data->t_type[4], ptr_mtktscpu_data->bind4,
- &ptr_mtktscpu_data->trip[5], &ptr_mtktscpu_data->t_type[5], ptr_mtktscpu_data->bind5,
- &ptr_mtktscpu_data->trip[6], &ptr_mtktscpu_data->t_type[6], ptr_mtktscpu_data->bind6,
- &ptr_mtktscpu_data->trip[7], &ptr_mtktscpu_data->t_type[7], ptr_mtktscpu_data->bind7,
- &ptr_mtktscpu_data->trip[8], &ptr_mtktscpu_data->t_type[8], ptr_mtktscpu_data->bind8,
- &ptr_mtktscpu_data->trip[9], &ptr_mtktscpu_data->t_type[9], ptr_mtktscpu_data->bind9,
- &ptr_mtktscpu_data->time_msec) == 32) {
- tscpu_dprintk("tscpu_write tscpu_unregister_thermal MA_len_temp=%d\n", MA_len_temp);
- /* modify for PTPOD, if disable Thermal,
- PTPOD still need to use this function for getting temperature
- */
- tscpu_unregister_thermal();
- if (num_trip < 0 || num_trip > 10) {
- aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT, "tscpu_write",
- "Bad argument");
- tscpu_dprintk("tscpu_write bad argument\n");
- kfree(ptr_mtktscpu_data);
- return -EINVAL;
- }
- for (i = 0; i < num_trip; i++)
- g_THERMAL_TRIP[i] = ptr_mtktscpu_data->t_type[i];
- g_bind0[0] = g_bind1[0] = g_bind2[0] = g_bind3[0] = g_bind4[0] = g_bind5[0] =
- g_bind6[0] = g_bind7[0] = g_bind8[0] = g_bind9[0] = '\0';
- for (i = 0; i < 20; i++) {
- g_bind0[i] = ptr_mtktscpu_data->bind0[i];
- g_bind1[i] = ptr_mtktscpu_data->bind1[i];
- g_bind2[i] = ptr_mtktscpu_data->bind2[i];
- g_bind3[i] = ptr_mtktscpu_data->bind3[i];
- g_bind4[i] = ptr_mtktscpu_data->bind4[i];
- g_bind5[i] = ptr_mtktscpu_data->bind5[i];
- g_bind6[i] = ptr_mtktscpu_data->bind6[i];
- g_bind7[i] = ptr_mtktscpu_data->bind7[i];
- g_bind8[i] = ptr_mtktscpu_data->bind8[i];
- g_bind9[i] = ptr_mtktscpu_data->bind9[i];
- }
- #if CPT_ADAPTIVE_AP_COOLER
- /* initialize... */
- for (i = 0; i < MAX_CPT_ADAPTIVE_COOLERS; i++)
- TARGET_TJS[i] = 117000;
- if (!strncmp(&ptr_mtktscpu_data->bind0[0], adaptive_cooler_name, 13))
- if ((ptr_mtktscpu_data->bind0[13] - '0') >= 0 &&
- (ptr_mtktscpu_data->bind0[13] - '0') < MAX_CPT_ADAPTIVE_COOLERS)
- TARGET_TJS[(ptr_mtktscpu_data->bind0[13] - '0')] = ptr_mtktscpu_data->trip[0];
- if (!strncmp(&ptr_mtktscpu_data->bind1[0], adaptive_cooler_name, 13))
- if ((ptr_mtktscpu_data->bind1[13] - '0') >= 0 &&
- (ptr_mtktscpu_data->bind1[13] - '0') < MAX_CPT_ADAPTIVE_COOLERS)
- TARGET_TJS[(ptr_mtktscpu_data->bind1[13] - '0')] = ptr_mtktscpu_data->trip[1];
- if (!strncmp(&ptr_mtktscpu_data->bind2[0], adaptive_cooler_name, 13))
- if ((ptr_mtktscpu_data->bind2[13] - '0') >= 0 &&
- (ptr_mtktscpu_data->bind2[13] - '0') < MAX_CPT_ADAPTIVE_COOLERS)
- TARGET_TJS[(ptr_mtktscpu_data->bind2[13] - '0')] = ptr_mtktscpu_data->trip[2];
- if (!strncmp(&ptr_mtktscpu_data->bind3[0], adaptive_cooler_name, 13))
- if ((ptr_mtktscpu_data->bind3[13] - '0') >= 0 &&
- (ptr_mtktscpu_data->bind3[13] - '0') < MAX_CPT_ADAPTIVE_COOLERS)
- TARGET_TJS[(ptr_mtktscpu_data->bind3[13] - '0')] = ptr_mtktscpu_data->trip[3];
- if (!strncmp(&ptr_mtktscpu_data->bind4[0], adaptive_cooler_name, 13))
- if ((ptr_mtktscpu_data->bind4[13] - '0') >= 0 &&
- (ptr_mtktscpu_data->bind4[13] - '0') < MAX_CPT_ADAPTIVE_COOLERS)
- TARGET_TJS[(ptr_mtktscpu_data->bind4[13] - '0')] = ptr_mtktscpu_data->trip[4];
- if (!strncmp(&ptr_mtktscpu_data->bind5[0], adaptive_cooler_name, 13))
- if ((ptr_mtktscpu_data->bind5[13] - '0') >= 0 &&
- (ptr_mtktscpu_data->bind5[13] - '0') < MAX_CPT_ADAPTIVE_COOLERS)
- TARGET_TJS[(ptr_mtktscpu_data->bind5[13] - '0')] = ptr_mtktscpu_data->trip[5];
- if (!strncmp(&ptr_mtktscpu_data->bind6[0], adaptive_cooler_name, 13))
- if ((ptr_mtktscpu_data->bind6[13] - '0') >= 0 &&
- (ptr_mtktscpu_data->bind6[13] - '0') < MAX_CPT_ADAPTIVE_COOLERS)
- TARGET_TJS[(ptr_mtktscpu_data->bind6[13] - '0')] = ptr_mtktscpu_data->trip[6];
- if (!strncmp(&ptr_mtktscpu_data->bind7[0], adaptive_cooler_name, 13))
- if ((ptr_mtktscpu_data->bind7[13] - '0') >= 0 &&
- (ptr_mtktscpu_data->bind7[13] - '0') < MAX_CPT_ADAPTIVE_COOLERS)
- TARGET_TJS[(ptr_mtktscpu_data->bind7[13] - '0')] = ptr_mtktscpu_data->trip[7];
- if (!strncmp(&ptr_mtktscpu_data->bind8[0], adaptive_cooler_name, 13))
- if ((ptr_mtktscpu_data->bind8[13] - '0') >= 0 &&
- (ptr_mtktscpu_data->bind8[13] - '0') < MAX_CPT_ADAPTIVE_COOLERS)
- TARGET_TJS[(ptr_mtktscpu_data->bind8[13] - '0')] = ptr_mtktscpu_data->trip[8];
- if (!strncmp(&ptr_mtktscpu_data->bind9[0], adaptive_cooler_name, 13))
- if ((ptr_mtktscpu_data->bind9[13] - '0') >= 0 &&
- (ptr_mtktscpu_data->bind9[13] - '0') < MAX_CPT_ADAPTIVE_COOLERS)
- TARGET_TJS[(ptr_mtktscpu_data->bind9[13] - '0')] = ptr_mtktscpu_data->trip[9];
- tscpu_dprintk("tscpu_write TTJ0=%d, TTJ1=%d, TTJ2=%d\n", TARGET_TJS[0],
- TARGET_TJS[1], TARGET_TJS[2]);
- #endif
- tscpu_dprintk("tscpu_write g_THERMAL_TRIP_0=%d,g_THERMAL_TRIP_1=%d,g_THERMAL_TRIP_2=%d,",
- g_THERMAL_TRIP[0], g_THERMAL_TRIP[1], g_THERMAL_TRIP[2]);
- tscpu_dprintk("g_THERMAL_TRIP_3=%d,g_THERMAL_TRIP_4=%d,g_THERMAL_TRIP_5=%d,g_THERMAL_TRIP_6=%d,",
- g_THERMAL_TRIP[3], g_THERMAL_TRIP[4], g_THERMAL_TRIP[5], g_THERMAL_TRIP[6]);
- tscpu_dprintk("g_THERMAL_TRIP_7=%d,g_THERMAL_TRIP_8=%d,g_THERMAL_TRIP_9=%d,\n",
- g_THERMAL_TRIP[7], g_THERMAL_TRIP[8], g_THERMAL_TRIP[9]);
- tscpu_dprintk("tscpu_write cooldev0=%s,cooldev1=%s,cooldev2=%s,cooldev3=%s,cooldev4=%s,",
- g_bind0, g_bind1, g_bind2, g_bind3, g_bind4);
- tscpu_dprintk("cooldev5=%s,cooldev6=%s,cooldev7=%s,cooldev8=%s,cooldev9=%s\n",
- g_bind5, g_bind6, g_bind7, g_bind8, g_bind9);
- for (i = 0; i < num_trip; i++)
- trip_temp[i] = ptr_mtktscpu_data->trip[i];
- interval = ptr_mtktscpu_data->time_msec;
- tscpu_dprintk("tscpu_write trip_0_temp=%d,trip_1_temp=%d,trip_2_temp=%d,trip_3_temp=%d,trip_4_temp=%d,",
- trip_temp[0], trip_temp[1], trip_temp[2], trip_temp[3], trip_temp[4]);
- tscpu_dprintk("trip_5_temp=%d,trip_6_temp=%d,trip_7_temp=%d,trip_8_temp=%d,trip_9_temp=%d,",
- trip_temp[5], trip_temp[6], trip_temp[7], trip_temp[8], trip_temp[9]);
- tscpu_dprintk("time_ms=%d, num_trip=%d\n", interval, num_trip);
- /* get temp, set high low threshold */
- /*
- curr_temp = get_immediate_temp();
- for(i=0; i<num_trip; i++)
- {
- if(curr_temp>trip_temp[i])
- break;
- }
- if(i==0)
- {
- tscpu_printk("tscpu_write setting error");
- }
- else if(i==num_trip)
- set_high_low_threshold(trip_temp[i-1], 10000);
- else
- set_high_low_threshold(trip_temp[i-1], trip_temp[i]);
- */
- tscpu_dprintk("tscpu_write tscpu_register_thermal\n");
- tscpu_register_thermal();
- proc_write_flag = 1;
- kfree(ptr_mtktscpu_data);
- return count;
- }
- tscpu_dprintk("tscpu_write bad argument\n");
- aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT, "tscpu_write",
- "Bad argument");
- kfree(ptr_mtktscpu_data);
- return -EINVAL;
- }
- static int tscpu_register_thermal(void)
- {
- tscpu_dprintk("tscpu_register_thermal\n");
- /* trips : trip 0~3 */
- thz_dev = mtk_thermal_zone_device_register("mtktscpu", num_trip, NULL,
- &mtktscpu_dev_ops, 0, 0, 0, interval);
- return 0;
- }
- static void tscpu_unregister_thermal(void)
- {
- tscpu_dprintk("tscpu_unregister_thermal\n");
- if (thz_dev) {
- mtk_thermal_zone_device_unregister(thz_dev);
- thz_dev = NULL;
- }
- }
- /* pause ALL periodoc temperature sensing point */
- static void thermal_pause_all_periodoc_temp_sensing(void)
- {
- int i = 0;
- unsigned long flags;
- int temp;
- /* tscpu_printk("thermal_pause_all_periodoc_temp_sensing\n"); */
- mt_ptp_lock(&flags);
- /*config bank0,1,2 */
- for (i = 0; i < TS_LEN_ARRAY(tscpu_g_bank); i++) {
- tscpu_switch_bank(i);
- temp = DRV_Reg32(TEMPMSRCTL1);
- /* set bit8=bit1=bit2=bit3=1 to pause sensing point 0,1,2,3 */
- DRV_WriteReg32(TEMPMSRCTL1, (temp | 0x10E));
- }
- mt_ptp_unlock(&flags);
- }
- /* release ALL periodoc temperature sensing point */
- static void thermal_release_all_periodoc_temp_sensing(void)
- {
- int i = 0;
- unsigned long flags;
- int temp;
- /* tscpu_printk("thermal_release_all_periodoc_temp_sensing\n"); */
- mt_ptp_lock(&flags);
- /*config bank0,1,2 */
- for (i = 0; i < TS_LEN_ARRAY(tscpu_g_bank); i++) {
- tscpu_switch_bank(i);
- temp = DRV_Reg32(TEMPMSRCTL1);
- /* set bit1=bit2=bit3=0 to release sensing point 0,1,2 */
- DRV_WriteReg32(TEMPMSRCTL1, ((temp & (~0x10E))));
- }
- mt_ptp_unlock(&flags);
- }
- void tscpu_thermal_enable_all_periodoc_sensing_point(thermal_bank_name bank_num)
- {
- switch (tscpu_g_bank[bank_num].ts_number) {
- case 1:
- /* enable periodoc temperature sensing point 0 */
- THERMAL_WRAP_WR32(0x00000001, TEMPMONCTL0);
- break;
- case 2:
- /* enable periodoc temperature sensing point 0,1 */
- THERMAL_WRAP_WR32(0x00000003, TEMPMONCTL0);
- break;
- case 3:
- /* enable periodoc temperature sensing point 0,1,2 */
- THERMAL_WRAP_WR32(0x00000007, TEMPMONCTL0);
- break;
- default:
- tscpu_printk("Error at %s\n", __func__);
- break;
- }
- }
- /* disable ALL periodoc temperature sensing point */
- static void thermal_disable_all_periodoc_temp_sensing(void)
- {
- int i = 0;
- unsigned long flags;
- /* tscpu_printk("thermal_disable_all_periodoc_temp_sensing\n"); */
- mt_ptp_lock(&flags);
- /*config bank0,1,2 */
- for (i = 0; i < TS_LEN_ARRAY(tscpu_g_bank); i++) {
- tscpu_switch_bank(i);
- /* tscpu_printk("thermal_disable_all_periodoc_temp_sensing:Bank_%d\n",i); */
- THERMAL_WRAP_WR32(0x00000000, TEMPMONCTL0);
- }
- mt_ptp_unlock(&flags);
- }
- static void tscpu_clear_all_temp(void)
- {
- /* 26111 to avoid ptpod judge <25deg will not update voltage. */
- /* CPU_TS_MCU2_T=26111; */
- /* GPU_TS_MCU1_T=26111; */
- /* LTE_TS_MCU3_T=26111; */
- int i = 0;
- int j = 0;
- for (i = 0; i < TS_LEN_ARRAY(tscpu_g_bank); i++) {
- for (j = 0; j < tscpu_g_bank[i].ts_number; j++)
- tscpu_bank_ts[i][tscpu_g_bank[i].ts[j].type] = CLEAR_TEMP;
- }
- }
- /*tscpu_thermal_suspend spend 1000us~1310us*/
- static int tscpu_thermal_suspend(struct platform_device *dev, pm_message_t state)
- {
- int cnt = 0;
- int temp = 0;
- tscpu_printk("tscpu_thermal_suspend\n");
- #if THERMAL_PERFORMANCE_PROFILE
- struct timeval begin, end;
- unsigned long val;
- do_gettimeofday(&begin);
- #endif
- g_tc_resume = 1; /* set "1", don't read temp during suspend */
- if (talking_flag == false) {
- tscpu_dprintk("tscpu_thermal_suspend no talking\n");
- #if (CONFIG_THERMAL_AEE_RR_REC == 1)
- aee_rr_rec_thermal_status(TSCPU_SUSPEND);
- #endif
- while (cnt < 50) {
- temp = (DRV_Reg32(THAHBST0) >> 16);
- if (cnt > 10)
- pr_debug("THAHBST0 = 0x%x,cnt=%d, %d\n", temp, cnt,
- __LINE__);
- if (temp == 0x0) {
- /* pause all periodoc temperature sensing point 0~2 */
- thermal_pause_all_periodoc_temp_sensing(); /* TEMPMSRCTL1 */
- break;
- }
- udelay(2);
- cnt++;
- }
- /* disable periodic temp measurement on sensor 0~2 */
- thermal_disable_all_periodoc_temp_sensing(); /* TEMPMONCTL0 */
- /* tscpu_thermal_clock_off(); */
- /*TSCON1[5:4]=2'b11, Buffer off */
- /* turn off the sensor buffer to save power */
- THERMAL_WRAP_WR32(DRV_Reg32(TS_CONFIGURE) | TS_TURN_OFF, TS_CONFIGURE);
- }
- #if THERMAL_PERFORMANCE_PROFILE
- do_gettimeofday(&end);
- /* Get milliseconds */
- pr_debug("suspend time spent, sec : %lu , usec : %lu\n", (end.tv_sec - begin.tv_sec),
- (end.tv_usec - begin.tv_usec));
- #endif
- return 0;
- }
- /*tscpu_thermal_suspend spend 3000us~4000us*/
- static int tscpu_thermal_resume(struct platform_device *dev)
- {
- int temp = 0;
- int cnt = 0;
- tscpu_printk("tscpu_thermal_resume\n");
- g_tc_resume = 1; /* set "1", don't read temp during start resume */
- if (talking_flag == false) {
- #if (CONFIG_THERMAL_AEE_RR_REC == 1)
- aee_rr_rec_thermal_status(TSCPU_RESUME);
- #endif
- tscpu_reset_thermal();
- temp = DRV_Reg32(TS_CONFIGURE);
- temp &= ~(TS_TURN_OFF); /* TS_CON1[5:4]=2'b00, 00: Buffer on, TSMCU to AUXADC */
- THERMAL_WRAP_WR32(temp, TS_CONFIGURE); /* read abb need */
- /* RG_TS2AUXADC < set from 2'b11 to 2'b00
- when resume.wait 100uS than turn on thermal controller. */
- udelay(200);
- /*add this function to read all temp first to avoid
- write TEMPPROTTC first time will issue an fake signal to RGU */
- tscpu_fast_initial_sw_workaround();
- while (cnt < 50) {
- temp = (DRV_Reg32(THAHBST0) >> 16);
- if (cnt > 10)
- pr_debug("THAHBST0 = 0x%x,cnt=%d, %d\n", temp, cnt, __LINE__);
- if (temp == 0x0) {
- /* pause all periodoc temperature sensing point 0~2 */
- thermal_pause_all_periodoc_temp_sensing(); /* TEMPMSRCTL1 */
- break;
- }
- udelay(2);
- cnt++;
- }
- thermal_disable_all_periodoc_temp_sensing(); /* TEMPMONCTL0 */
- tscpu_thermal_initial_all_bank();
- thermal_release_all_periodoc_temp_sensing(); /* must release before start */
- tscpu_clear_all_temp();
- tscpu_config_all_tc_hw_protect(trip_temp[0], tc_mid_trip);
- }
- g_tc_resume = 2; /* set "2", resume finish,can read temp */
- return 0;
- }
- static struct platform_driver mtk_thermal_driver = {
- .remove = NULL,
- .shutdown = NULL,
- .probe = tscpu_thermal_probe,
- .suspend = tscpu_thermal_suspend,
- .resume = tscpu_thermal_resume,
- .driver = {
- .name = THERMAL_NAME,
- #ifdef CONFIG_OF
- .of_match_table = mt_thermal_of_match,
- #endif
- },
- };
- #if MTK_TS_CPU_RT
- static int ktp_limited = -275000;
- static int ktp_thread(void *arg)
- {
- int max_temp = 0;
- int bank0_T;
- struct sched_param param = {.sched_priority = 98 };
- sched_setscheduler(current, SCHED_FIFO, ¶m);
- set_current_state(TASK_INTERRUPTIBLE);
- tscpu_printk("ktp_thread 1st run\n");
- schedule();
- for (;;) {
- int temp_tc_mid_trip = tc_mid_trip;
- int temp_ktp_limited = ktp_limited;
- tscpu_printk("ktp_thread awake,tc_mid_trip=%d\n", tc_mid_trip);
- if (kthread_should_stop())
- break;
- /* bank0_T = MAX(MAX(CPU_TS_MCU2_T,GPU_TS_MCU1_T),LTE_TS_MCU3_T); */
- bank0_T = tscpu_max_temperature();
- max_temp = bank0_T;
- tscpu_warn("ktp_thread temp=%d\n", max_temp);
- if ((temp_tc_mid_trip > -275000) && (max_temp >= (temp_tc_mid_trip - 5000))) {
- /* trip_temp[1] should be shutdown point... */
- /* Do what ever we want */
- tscpu_dprintk("ktp_thread overheat %d\n", max_temp);
- /* freq/volt down or cpu down or backlight down or charging down... */
- #if defined(CONFIG_ARCH_MT6755)
- mt_ppm_cpu_thermal_protect(600); /*D1 max~1600mW,min~600 */
- #else
- mt_cpufreq_thermal_protect(600); /*D1 max~1600mW,min~600 */
- #endif
- mt_gpufreq_thermal_protect(600); /*D1 max~900mW,min~600mW */
- ktp_limited = temp_tc_mid_trip;
- msleep(20 * 1000);
- } else if ((temp_ktp_limited > -275000) && (max_temp < temp_ktp_limited)) {
- unsigned int final_limit;
- final_limit = MIN(static_cpu_power_limit, adaptive_cpu_power_limit);
- tscpu_dprintk("ktp_thread unlimit cpu=%d\n", final_limit);
- #if defined(CONFIG_ARCH_MT6755)
- mt_ppm_cpu_thermal_protect((final_limit != 0x7FFFFFFF) ? final_limit : 0);
- #else
- mt_cpufreq_thermal_protect((final_limit != 0x7FFFFFFF) ? final_limit : 0);
- #endif
- final_limit = MIN(static_gpu_power_limit, adaptive_gpu_power_limit);
- tscpu_dprintk("ktp_thread unlimit gpu=%d\n", final_limit);
- mt_gpufreq_thermal_protect((final_limit != 0x7FFFFFFF) ? final_limit : 0);
- ktp_limited = -275000;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- } else {
- tscpu_dprintk("ktp_thread else temp=%d, trip=%d, ltd=%d\n", max_temp,
- temp_tc_mid_trip, temp_ktp_limited);
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- }
- }
- tscpu_dprintk("ktp_thread stopped\n");
- return 0;
- }
- #endif
- int tscpu_get_temp_by_bank(thermal_bank_name ts_bank)
- {
- int bank_T = 0;
- tscpu_dprintk("tscpu_get_temp %s, %d\n", __func__, __LINE__);
- if (ts_bank < TS_LEN_ARRAY(tscpu_g_bank))
- bank_T = max_temperature_in_bank(ts_bank);
- else
- panic("Bank number out of range\n");
- return bank_T;
- }
- #if THERMAL_GPIO_OUT_TOGGLE
- static int tscpu_GPIO_out(struct inode *inode, struct file *file)
- {
- return single_open(file, tscpu_read_GPIO_out, NULL);
- }
- static const struct file_operations mtktscpu_GPIO_out_fops = {
- .owner = THIS_MODULE,
- .open = tscpu_GPIO_out,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = tscpu_write_GPIO_out,
- .release = single_release,
- };
- #endif
- static int tscpu_Tj_out(struct inode *inode, struct file *file)
- {
- return single_open(file, tscpu_read_Tj_out, NULL);
- }
- static const struct file_operations mtktscpu_Tj_out_fops = {
- .owner = THIS_MODULE,
- .open = tscpu_Tj_out,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = tscpu_write_Tj_out,
- .release = single_release,
- };
- static int tscpu_open_opp(struct inode *inode, struct file *file)
- {
- return single_open(file, tscpu_read_opp, NULL);
- }
- static const struct file_operations mtktscpu_opp_fops = {
- .owner = THIS_MODULE,
- .open = tscpu_open_opp,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- };
- static int tscpu_open_log(struct inode *inode, struct file *file)
- {
- return single_open(file, tscpu_read_log, NULL);
- }
- static const struct file_operations mtktscpu_log_fops = {
- .owner = THIS_MODULE,
- .open = tscpu_open_log,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = tscpu_write_log,
- .release = single_release,
- };
- static int tscpu_open(struct inode *inode, struct file *file)
- {
- return single_open(file, tscpu_read, NULL);
- }
- static const struct file_operations mtktscpu_fops = {
- .owner = THIS_MODULE,
- .open = tscpu_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = tscpu_write,
- .release = single_release,
- };
- #if defined(CONFIG_ARCH_MT6753)
- /*For MT6753 PMIC 5A throttle patch*/
- static int tzcpu_cpufreq5A_read(struct seq_file *m, void *v)
- {
- seq_printf(m, "Thermal 5A threshold= %d\n", thermal5A_TH);
- return 0;
- }
- static ssize_t tzcpu_cpufreq5A_write(struct file *file, const char __user *buffer, size_t count, loff_t *data)
- {
- char desc[32];
- int th;
- int len = 0;
- len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
- if (copy_from_user(desc, buffer, len))
- return 0;
- desc[len] = '\0';
- if (kstrtoint(desc, 10, &th) == 0) {
- thermal5A_TH = th;
- return count;
- }
- tscpu_printk(" bad argument\n");
- return -EINVAL;
- }
- static int tzcpu_cpufreq5A_open(struct inode *inode, struct file *file)
- {
- return single_open(file, tzcpu_cpufreq5A_read, NULL);
- }
- static const struct file_operations tzcpu_cpufreq5A_fops = {
- .owner = THIS_MODULE,
- .open = tzcpu_cpufreq5A_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = tzcpu_cpufreq5A_write,
- .release = single_release,
- };
- #endif
- static int tscpu_cal_open(struct inode *inode, struct file *file)
- {
- return single_open(file, tscpu_read_cal, NULL);
- }
- static const struct file_operations mtktscpu_cal_fops = {
- .owner = THIS_MODULE,
- .open = tscpu_cal_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- };
- static int tscpu_read_temperature_open(struct inode *inode, struct file *file)
- {
- return single_open(file, tscpu_read_temperature_info, NULL);
- }
- static const struct file_operations mtktscpu_read_temperature_fops = {
- .owner = THIS_MODULE,
- .open = tscpu_read_temperature_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = tscpu_write,
- .release = single_release,
- };
- static int tscpu_set_temperature_open(struct inode *inode, struct file *file)
- {
- return single_open(file, tscpu_set_temperature_read, NULL);
- }
- static const struct file_operations mtktscpu_set_temperature_fops = {
- .owner = THIS_MODULE,
- .open = tscpu_set_temperature_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = tscpu_set_temperature_write,
- .release = single_release,
- };
- static int tscpu_talking_flag_open(struct inode *inode, struct file *file)
- {
- return single_open(file, tscpu_talking_flag_read, NULL);
- }
- static const struct file_operations mtktscpu_talking_flag_fops = {
- .owner = THIS_MODULE,
- .open = tscpu_talking_flag_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = tscpu_talking_flag_write,
- .release = single_release,
- };
- #if MTKTSCPU_FAST_POLLING
- static int tscpu_fastpoll_open(struct inode *inode, struct file *file)
- {
- return single_open(file, tscpu_read_fastpoll, NULL);
- }
- static const struct file_operations mtktscpu_fastpoll_fops = {
- .owner = THIS_MODULE,
- .open = tscpu_fastpoll_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .write = tscpu_write_fastpoll,
- .release = single_release,
- };
- #endif
- #if THERMAL_DRV_UPDATE_TEMP_DIRECT_TO_MET
- int tscpu_get_cpu_temp_met(MTK_THERMAL_SENSOR_CPU_ID_MET id)
- {
- unsigned long flags;
- int ret;
- if (id < 0 || id >= MTK_THERMAL_SENSOR_CPU_COUNT)
- return -127000;
- if (ATM_CPU_LIMIT == id)
- return (adaptive_cpu_power_limit != 0x7FFFFFFF) ? adaptive_cpu_power_limit : 0;
- if (ATM_GPU_LIMIT == id)
- return (adaptive_gpu_power_limit != 0x7FFFFFFF) ? adaptive_gpu_power_limit : 0;
- tscpu_met_lock(&flags);
- if (a_tscpu_all_temp[id] == 0) {
- tscpu_met_unlock(&flags);
- return -127000;
- }
- ret = a_tscpu_all_temp[id];
- tscpu_met_unlock(&flags);
- return ret;
- }
- EXPORT_SYMBOL(tscpu_get_cpu_temp_met);
- #endif
- #if defined(CONFIG_ARCH_MT6755)
- #if 0
- static int thermal_auxadc_get_data(int times, int channel)
- {
- int ret = 0, data[4], i, ret_value = 0, ret_temp = 0;
- pr_err("Thermal_auxadc_get_data\n");
- if (IMM_IsAdcInitReady() == 0) {
- pr_err("[thermal_auxadc_get_data]: AUXADC is not ready\n");
- return 0;
- }
- for (i = 0; i < times; i++) {
- ret_value = IMM_GetOneChannelValue(channel, data, &ret_temp);
- pr_err("[thermal_auxadc_get_data]: raw%d= %d\n", i, ret_temp);
- ret += ret_temp;
- }
- ret = ret / times;
- return ret;
- }
- #endif
- /*Patch to pause thermal controller and turn off auxadc GC.
- For mt6755 only*/
- #if 1
- static void tscpu_thermal_pause(void)
- {
- int cnt = 0;
- int temp = 0;
- aee_rr_rec_thermal_status(TSCPU_PAUSE);
- thermal_pause_all_periodoc_temp_sensing(); /* TEMPMSRCTL1 */
- do {
- temp = (DRV_Reg32(THAHBST0) >> 16);
- if (cnt > 10)
- pr_err("THAHBST0 = 0x%x, cnt = %d, %d\n", temp, cnt, __LINE__);
- udelay(2);
- cnt++;
- } while (temp != 0x0 && cnt < 50);
- /* disable periodic temp measurement on sensor 0~2 */
- thermal_disable_all_periodoc_temp_sensing(); /* TEMPMONCTL0 */
- #if !defined(CONFIG_MTK_CLKMGR)
- if (therm_auxadc)
- clk_disable_unprepare(therm_auxadc);
- #endif
- }
- static void tscpu_thermal_release(void)
- {
- int temp = 0;
- int cnt = 0;
- aee_rr_rec_thermal_status(TSCPU_RELEASE);
- #if !defined(CONFIG_MTK_CLKMGR)
- if (therm_auxadc)
- clk_prepare_enable(therm_auxadc);
- #endif
- /*thermal_auxadc_get_data(2, 11);*/
- thermal_release_all_periodoc_temp_sensing(); /* must release before start */
- tscpu_fast_initial_sw_workaround();
- thermal_pause_all_periodoc_temp_sensing(); /* TEMPMSRCTL1 */
- do {
- temp = (DRV_Reg32(THAHBST0) >> 16);
- if (cnt > 10)
- pr_err("THAHBST0 = 0x%x, cnt = %d, %d\n", temp, cnt, __LINE__);
- udelay(2);
- cnt++;
- } while (temp != 0x0 && cnt < 50);
- thermal_disable_all_periodoc_temp_sensing(); /* TEMPMONCTL0 */
- tscpu_thermal_initial_all_bank();
- thermal_release_all_periodoc_temp_sensing(); /* must release before start */
- }
- #else
- static void tscpu_thermal_pause(void)
- {
- int cnt = 0, temp = 0;
- aee_rr_rec_thermal_status(TSCPU_PAUSE);
- thermal_pause_all_periodoc_temp_sensing(); /* TEMPMSRCTL1 */
- thermal_disable_all_periodoc_temp_sensing(); /* TEMPMONCTL0 */
- while (temp != 0x0 && cnt < 50) {
- temp = (DRV_Reg32(THAHBST0) >> 16);
- if (cnt > 10)
- tscpu_printk("THAHBST0 = 0x%x, cnt = %d, %d\n", temp, cnt, __LINE__);
- udelay(2);
- cnt++;
- }
- #if !defined(CONFIG_MTK_CLKMGR)
- if (therm_auxadc)
- clk_disable_unprepare(therm_auxadc);
- #endif
- }
- static void tscpu_thermal_release(void)
- {
- int i = 0;
- unsigned long flags;
- aee_rr_rec_thermal_status(TSCPU_RELEASE);
- #if !defined(CONFIG_MTK_CLKMGR)
- if (therm_auxadc)
- clk_prepare_enable(therm_auxadc);
- #endif
- thermal_release_all_periodoc_temp_sensing(); /* must release before start */
- mt_ptp_lock(&flags);
- for (i = 0; i < TS_LEN_ARRAY(tscpu_g_bank); i++) {
- tscpu_switch_bank(i);
- tscpu_thermal_enable_all_periodoc_sensing_point(i);
- }
- mt_ptp_unlock(&flags);
- }
- #endif
- #endif
- static DEFINE_SPINLOCK(temp_valid_spinlock);
- static void temp_valid_lock(unsigned long *flags)
- {
- spin_lock_irqsave(&temp_valid_spinlock, *flags);
- }
- static void temp_valid_unlock(unsigned long *flags)
- {
- spin_unlock_irqrestore(&temp_valid_spinlock, *flags);
- }
- static void check_all_temp_valid(void)
- {
- int i, j, raw;
- for (i = 0; i < ARRAY_SIZE(tscpu_g_bank); i++) {
- for (j = 0; j < tscpu_g_bank[i].ts_number; j++) {
- raw = tscpu_bank_ts_r[i][tscpu_g_bank[i].ts[j].type];
- if (raw == THERMAL_INIT_VALUE)
- return; /* The temperature is not valid. */
- }
- }
- g_is_temp_valid = 1;
- }
- int tscpu_is_temp_valid(void)
- {
- int is_valid = 0;
- unsigned long flags;
- temp_valid_lock(&flags);
- if (g_is_temp_valid == 0)
- check_all_temp_valid();
- is_valid = g_is_temp_valid;
- temp_valid_unlock(&flags);
- return is_valid;
- }
- static void read_all_bank_temperature(void)
- {
- int i = 0;
- int j = 0;
- unsigned long flags;
- mt_ptp_lock(&flags);
- for (i = 0; i < TS_LEN_ARRAY(tscpu_g_bank); i++) {
- tscpu_switch_bank(i);
- for (j = 0; j < tscpu_g_bank[i].ts_number; j++)
- tscpu_thermal_read_bank_temp(i, tscpu_g_bank[i].ts[j].type, j);
- }
- mt_ptp_unlock(&flags);
- tscpu_is_temp_valid();
- }
- void tscpu_update_tempinfo(void)
- {
- unsigned long flags;
- if (g_tc_resume == 0)
- read_all_bank_temperature();
- else if (g_tc_resume == 2) /* resume ready */
- g_tc_resume = 0;
- #if (CONFIG_THERMAL_AEE_RR_REC == 1)
- aee_rr_rec_thermal_temp1(get_immediate_ts1_wrap() / 1000);
- aee_rr_rec_thermal_temp2(get_immediate_ts2_wrap() / 1000);
- aee_rr_rec_thermal_temp3(get_immediate_ts3_wrap() / 1000);
- aee_rr_rec_thermal_temp4(get_immediate_ts4_wrap() / 1000);
- aee_rr_rec_thermal_temp5(get_immediate_tsabb_wrap() / 1000);
- aee_rr_rec_thermal_status(TSCPU_NORMAL);
- #endif
- #if THERMAL_DRV_UPDATE_TEMP_DIRECT_TO_MET
- tscpu_met_lock(&flags);
- tscpu_dprintk("tscpu_get_temp %s, %d\n", __func__, __LINE__);
- a_tscpu_all_temp[MTK_THERMAL_SENSOR_TS1] = get_immediate_ts1_wrap();
- a_tscpu_all_temp[MTK_THERMAL_SENSOR_TS2] = get_immediate_ts2_wrap();
- a_tscpu_all_temp[MTK_THERMAL_SENSOR_TS3] = get_immediate_ts3_wrap();
- a_tscpu_all_temp[MTK_THERMAL_SENSOR_TS4] = get_immediate_ts4_wrap();
- a_tscpu_all_temp[MTK_THERMAL_SENSOR_TSABB] = get_immediate_tsabb_wrap();
- tscpu_met_unlock(&flags);
- if (NULL != g_pThermalSampler)
- g_pThermalSampler();
- #endif
- #if 0
- pr_debug("\n\n");
- \\tscpu_printk("\n tscpu_update_tempinfo, T=%d,%d,%d,%d,%d,%d\n", CPU_TS_MCU1_T,
- CPU_TS_MCU2_T, GPU_TS_MCU3_T, SOC_TS_MCU4_T, SOC_TS_MCU2_T, SOC_TS_MCU3_T);
- pr_debug("Bank 0 : CPU (TS_MCU1 = %d,TS_MCU2 = %d)\n", CPU_TS_MCU1_T,
- CPU_TS_MCU2_T);
- pr_debug("Bank 1 : GPU (TS_MCU3 = %d)\n", GPU_TS_MCU3_T);
- pr_debug("Bank 2 : SOC (TS_MCU4 = %d,TS_MCU2 = %d,TS_MCU3 = %d)\n", SOC_TS_MCU4_T,
- SOC_TS_MCU2_T, SOC_TS_MCU3_T);
- #endif
- }
- void tscpu_cancel_thermal_timer(void)
- {
- /* stop thermal framework polling when entering deep idle */
- if (thz_dev)
- cancel_delayed_work(&(thz_dev->poll_queue));
- #if defined(CONFIG_ARCH_MT6755)
- /*Patch to pause thermal controller and turn off auxadc GC.
- For mt6755 only*/
- tscpu_thermal_pause();
- #endif
- }
- void tscpu_start_thermal_timer(void)
- {
- /* resume thermal framework polling when leaving deep idle */
- if (thz_dev != NULL && interval != 0)
- mod_delayed_work(system_freezable_wq, &(thz_dev->poll_queue), round_jiffies(msecs_to_jiffies(1000)));
- #if defined(CONFIG_ARCH_MT6755)
- /*Patch to pause thermal controller and turn off auxadc GC.
- For mt6755 only*/
- tscpu_thermal_release();
- #endif
- }
- #ifdef CONFIG_OF
- long tscpu_dev_alloc_module_base_by_name(const char *name)
- {
- unsigned long VA;
- struct device_node *node = NULL;
- node = of_find_compatible_node(NULL, NULL, name);
- if (!node) {
- pr_debug("find node failed\n");
- return 0;
- }
- VA = (unsigned long)of_iomap(node, 0);
- pr_debug("DEV: VA(%s): 0x%lx\n", name, VA);
- return VA;
- }
- #endif
- static void init_thermal(void)
- {
- int temp = 0;
- int cnt = 0;
- #if (CONFIG_THERMAL_AEE_RR_REC == 1)
- _mt_thermal_aee_init();
- aee_rr_rec_thermal_status(TSCPU_INIT);
- #endif
- tscpu_thermal_cal_prepare();
- tscpu_thermal_cal_prepare_2(0);
- tscpu_reset_thermal();
- /* thermal spm verification */
- #if 0
- spm_write(SPM_SLEEP_WAKEUP_EVENT_MASK, ~(1U << 21)); /* unmask bit21 for thermal wake up source */
- tscpu_printk("SPM_SLEEP_WAKEUP_EVENT_MASK =0x%08x\n",
- spm_read(SPM_SLEEP_WAKEUP_EVENT_MASK));
- #endif
- /*
- TS_CON1 default is 0x30, this is buffer off
- we should turn on this buffer berore we use thermal sensor,
- or this buffer off will let TC read a very small value from auxadc
- and this small value will trigger thermal reboot
- */
- temp = DRV_Reg32(TS_CONFIGURE);
- temp &= ~(TS_TURN_OFF); /* TS_CON1[5:4]=2'b00, 00: Buffer on, TSMCU to AUXADC */
- THERMAL_WRAP_WR32(temp, TS_CONFIGURE); /* read abb need */
- /* RG_TS2AUXADC < set from 2'b11 to 2'b00
- when resume.wait 100uS than turn on thermal controller.*/
- udelay(200);
- BUG_ON((DRV_Reg32(TS_CONFIGURE) & TS_TURN_OFF) != 0x0);
- BUG_ON(IMM_IsAdcInitReady() != 1);
- /*add this function to read all temp first to avoid
- write TEMPPROTTC first will issue an fake signal to RGU */
- tscpu_fast_initial_sw_workaround();
- while (cnt < 50) {
- temp = (DRV_Reg32(THAHBST0) >> 16);
- if (cnt > 10)
- pr_debug("THAHBST0 = 0x%x,cnt=%d, %d\n", temp, cnt, __LINE__);
- if (temp == 0x0) {
- /* pause all periodoc temperature sensing point 0~2 */
- thermal_pause_all_periodoc_temp_sensing(); /* TEMPMSRCTL1 */
- break;
- }
- udelay(2);
- cnt++;
- }
- thermal_disable_all_periodoc_temp_sensing(); /* TEMPMONCTL0 */
- /* pr_debug(KERN_CRIT "cnt = %d, %d\n",cnt,__LINE__); */
- /*Normal initial */
- tscpu_thermal_initial_all_bank();
- thermal_release_all_periodoc_temp_sensing(); /* TEMPMSRCTL1 must release before start */
- read_all_bank_temperature();
- }
- static void tscpu_create_fs(void)
- {
- struct proc_dir_entry *entry = NULL;
- struct proc_dir_entry *mtktscpu_dir = NULL;
- mtktscpu_dir = mtk_thermal_get_proc_drv_therm_dir_entry();
- if (!mtktscpu_dir) {
- tscpu_printk("[%s]: mkdir /proc/driver/thermal failed\n", __func__);
- } else {
- entry =
- proc_create("tzcpu", S_IRUGO | S_IWUSR | S_IWGRP, mtktscpu_dir, &mtktscpu_fops);
- if (entry)
- proc_set_user(entry, uid, gid);
- #if defined(CONFIG_ARCH_MT6753)
- /*For MT6753 PMIC 5A throttle patch*/
- entry = proc_create("tzcpu_cpufreq5A", S_IRUGO | S_IWUSR | S_IWGRP,
- mtktscpu_dir, &tzcpu_cpufreq5A_fops);
- if (entry)
- proc_set_user(entry, uid, gid);
- #endif
- entry =
- proc_create("tzcpu_log", S_IRUGO | S_IWUSR, mtktscpu_dir, &mtktscpu_log_fops);
- entry = proc_create("thermlmt", S_IRUGO, NULL, &mtktscpu_opp_fops);
- entry = proc_create("tzcpu_cal", S_IRUSR, mtktscpu_dir, &mtktscpu_cal_fops);
- entry =
- proc_create("tzcpu_read_temperature", S_IRUGO, mtktscpu_dir,
- &mtktscpu_read_temperature_fops);
- entry =
- proc_create("tzcpu_set_temperature", S_IRUGO | S_IWUSR, mtktscpu_dir,
- &mtktscpu_set_temperature_fops);
- entry =
- proc_create("tzcpu_talking_flag", S_IRUGO | S_IWUSR, mtktscpu_dir,
- &mtktscpu_talking_flag_fops);
- #if MTKTSCPU_FAST_POLLING
- entry =
- proc_create("tzcpu_fastpoll", S_IRUGO | S_IWUSR | S_IWGRP, mtktscpu_dir,
- &mtktscpu_fastpoll_fops);
- if (entry)
- proc_set_user(entry, uid, gid);
- #endif /* #if MTKTSCPU_FAST_POLLING */
- entry =
- proc_create("tzcpu_Tj_out_via_HW_pin", S_IRUGO | S_IWUSR, mtktscpu_dir,
- &mtktscpu_Tj_out_fops);
- if (entry)
- proc_set_user(entry, uid, gid);
- #if THERMAL_GPIO_OUT_TOGGLE
- entry =
- proc_create("tzcpu_GPIO_out_monitor", S_IRUGO | S_IWUSR, mtktscpu_dir,
- &mtktscpu_GPIO_out_fops);
- if (entry)
- proc_set_user(entry, uid, gid);
- #endif
- }
- }
- /*must wait until AUXADC initial ready*/
- static int tscpu_thermal_probe(struct platform_device *dev)
- {
- int err = 0;
- tscpu_printk("thermal_prob\n");
- /*
- default is dule mode(irq/reset), if not to config this and hot happen,
- system will reset after 30 secs
- Thermal need to config to direct reset mode
- this API provide by Weiqi Fu(RGU SW owner).
- */
- if (get_io_reg_base() == 0)
- return 0;
- #if !defined(CONFIG_MTK_CLKMGR)
- #if defined(CONFIG_ARCH_MT6755)
- /*Patch to pause thermal controller and turn off auxadc GC.
- For mt6755 only*/
- therm_auxadc = devm_clk_get(&dev->dev, "therm-auxadc");
- if (IS_ERR(therm_auxadc))
- tscpu_printk("[auxadc] cannot get auxadc clock\n");
- tscpu_printk("[AUXADC]: auxadc CLK:0x%p\n", therm_auxadc);
- #endif
- therm_main = devm_clk_get(&dev->dev, "therm-main");
- if (IS_ERR(therm_main)) {
- tscpu_printk("cannot get thermal clock.\n");
- return PTR_ERR(therm_main);
- }
- tscpu_dprintk("therm-main Ptr=%p", therm_main);
- #endif
- tscpu_thermal_clock_on();
- init_thermal();
- #if MTK_TS_CPU_RT
- {
- tscpu_dprintk("tscpu_register_thermal creates kthermp\n");
- ktp_thread_handle = kthread_create(ktp_thread, (void *)NULL, "kthermp");
- if (IS_ERR(ktp_thread_handle)) {
- ktp_thread_handle = NULL;
- tscpu_printk("tscpu_register_thermal kthermp creation fails\n");
- goto err_unreg;
- }
- wake_up_process(ktp_thread_handle);
- }
- #endif
- #ifdef CONFIG_OF
- err =
- request_irq(thermal_irq_number, tscpu_thermal_all_bank_interrupt_handler,
- IRQF_TRIGGER_LOW, THERMAL_NAME, NULL);
- if (err)
- tscpu_warn("tscpu_init IRQ register fail\n");
- #else
- err =
- request_irq(THERM_CTRL_IRQ_BIT_ID, tscpu_thermal_all_bank_interrupt_handler,
- IRQF_TRIGGER_LOW, THERMAL_NAME, NULL);
- if (err)
- tscpu_warn("tscpu_init IRQ register fail\n");
- #endif
- tscpu_config_all_tc_hw_protect(trip_temp[0], tc_mid_trip);
- #if THERMAL_GET_AHB_BUS_CLOCK
- thermal_get_AHB_clk_info();
- #endif
- return err;
- }
- #if defined(CONFIG_ARCH_MT6753)
- /*For MT6753 PMIC 5A throttle patch*/
- int isMT6753T(void)
- {
- unsigned int cpu_spd_bond, efuse_spare2, is53T = 0;
- cpu_spd_bond = (get_devinfo_with_index(3) & _BITMASK_(2:0));
- efuse_spare2 = (get_devinfo_with_index(5) & _BITMASK_(21:20)) >> 20;
- switch (cpu_spd_bond) {
- case 0:
- if (efuse_spare2 == 3)
- is53T = 1;
- break;
- case 1:
- case 2:
- is53T = 1;
- break;
- default:
- break;
- }
- return is53T;
- }
- #endif
- static int __init tscpu_init(void)
- {
- int err = 0;
- tscpu_printk("tscpu_init\n");
- err = platform_driver_register(&mtk_thermal_driver);
- if (err) {
- tscpu_warn("thermal driver callback register failed..\n");
- return err;
- }
- err = tscpu_register_thermal();
- if (err) {
- tscpu_warn("tscpu_register_thermal fail\n");
- goto err_unreg;
- }
- #if defined(CONFIG_ARCH_MT6753)
- /*For MT6753 PMIC 5A throttle patch*/
- if (isMT6753T() == 0)
- fast_polling_trip_temp = 40000;
- #endif
- tscpu_create_fs();
- return 0;
- err_unreg:
- return err;
- }
- static void __exit tscpu_exit(void)
- {
- tscpu_dprintk("tscpu_exit\n");
- #if MTK_TS_CPU_RT
- if (ktp_thread_handle)
- kthread_stop(ktp_thread_handle);
- #endif
- tscpu_unregister_thermal();
- #if THERMAL_DRV_UPDATE_TEMP_DIRECT_TO_MET
- mt_thermalsampler_registerCB(NULL);
- #endif
- }
- module_init(tscpu_init);
- module_exit(tscpu_exit);
|