blob: d45fa44f2d0a88558f22b70fd75bfe75b1a87f6e [file] [log] [blame]
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -07001/*
2 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070031/* Changes from Qualcomm Innovation Center are provided under the following license:
32
Priyansh Jaind670d792022-07-20 15:51:13 +053033Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070034SPDX-License-Identifier: BSD-3-Clause-Clear */
35
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070036#include <cstdio>
37#include <cinttypes>
38#include <string>
39#include <dirent.h>
40#include <unordered_map>
41#include <fstream>
42
43#include <android-base/logging.h>
44#include "thermalCommon.h"
45
46#define MAX_LENGTH 50
47#define MAX_PATH (256)
48#define DEFAULT_HYSTERESIS 5000
49#define THERMAL_SYSFS "/sys/class/thermal/"
50#define TZ_DIR_NAME "thermal_zone"
51#define TZ_DIR_FMT "thermal_zone%d"
52#define TEMPERATURE_FILE_FORMAT "/sys/class/thermal/thermal_zone%d/temp"
53#define POLICY_FILE_FORMAT "/sys/class/thermal/thermal_zone%d/policy"
54#define TRIP_FILE_FORMAT "/sys/class/thermal/thermal_zone%d/trip_point_1_temp"
55#define HYST_FILE_FORMAT "/sys/class/thermal/thermal_zone%d/trip_point_1_hyst"
Manaf Meethalavalappu Pallikunhi4d2b7142024-08-22 01:18:41 +053056#define TRIP_TYPE_FILE_FORMAT "/sys/class/thermal/thermal_zone%d/trip_point_%d_type"
57#define TRIP_N_FILE_FORMAT "/sys/class/thermal/thermal_zone%d/trip_point_%d_temp"
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070058#define USER_SPACE_POLICY "user_space"
59#define TZ_TYPE "type"
60#define CDEV_DIR_NAME "cooling_device"
61#define CDEV_DIR_FMT "cooling_device%d"
62#define CDEV_CUR_STATE_PATH "/sys/class/thermal/cooling_device%d/cur_state"
63#define CPU_USAGE_FILE "/proc/stat"
64#define CPU_ONLINE_FILE_FORMAT "/sys/devices/system/cpu/cpu%d/online"
Manaf Meethalavalappu Pallikunhi4d2b7142024-08-22 01:18:41 +053065#define LIMIT_PROFILE_1_SD_TEMP 118000
66#define LIMIT_PROFILE_TRIP_TYPE "hot"
67#define LIMIT_PROFILE_SD_TZ "aoss-0"
68#define LIMIT_PROFILE_TRIP_MAX 11
69
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070070
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070071namespace aidl {
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070072namespace android {
73namespace hardware {
74namespace thermal {
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070075
76static std::unordered_map<std::string, cdevType> cdev_map = {
77 {"thermal-cpufreq-0", cdevType::CPU},
78 {"thermal-cpufreq-1", cdevType::CPU},
79 {"thermal-cpufreq-2", cdevType::CPU},
80 {"thermal-cpufreq-3", cdevType::CPU},
81 {"thermal-cpufreq-4", cdevType::CPU},
82 {"thermal-cpufreq-5", cdevType::CPU},
83 {"thermal-cpufreq-6", cdevType::CPU},
84 {"thermal-cpufreq-7", cdevType::CPU},
Manaf Meethalavalappu Pallikunhia2c882a2022-02-25 01:14:32 +053085 {"cpufreq-cpu0", cdevType::CPU},
86 {"cpufreq-cpu1", cdevType::CPU},
87 {"cpufreq-cpu2", cdevType::CPU},
88 {"cpufreq-cpu3", cdevType::CPU},
89 {"cpufreq-cpu4", cdevType::CPU},
90 {"cpufreq-cpu5", cdevType::CPU},
91 {"cpufreq-cpu6", cdevType::CPU},
92 {"cpufreq-cpu7", cdevType::CPU},
93 {"thermal-cluster-4-7", cdevType::CPU},
94 {"thermal-cluster-3-7", cdevType::CPU},
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070095 {"cpu-isolate0", cdevType::CPU},
96 {"cpu-isolate1", cdevType::CPU},
97 {"cpu-isolate2", cdevType::CPU},
98 {"cpu-isolate3", cdevType::CPU},
99 {"cpu-isolate4", cdevType::CPU},
100 {"cpu-isolate5", cdevType::CPU},
101 {"cpu-isolate6", cdevType::CPU},
102 {"cpu-isolate7", cdevType::CPU},
Manaf Meethalavalappu Pallikunhia2c882a2022-02-25 01:14:32 +0530103 {"thermal-pause-1", cdevType::CPU},
104 {"thermal-pause-2", cdevType::CPU},
105 {"thermal-pause-4", cdevType::CPU},
106 {"thermal-pause-8", cdevType::CPU},
107 {"thermal-pause-10", cdevType::CPU},
108 {"thermal-pause-20", cdevType::CPU},
109 {"thermal-pause-40", cdevType::CPU},
110 {"thermal-pause-80", cdevType::CPU},
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700111 {"thermal-devfreq-0", cdevType::GPU},
Manaf Meethalavalappu Pallikunhia2c882a2022-02-25 01:14:32 +0530112 {"devfreq-3d00000.qcom,kgsl-3d0", cdevType::GPU},
Manaf Meethalavalappu Pallikunhi5ad97e62022-04-05 15:53:49 +0530113 {"gpu", cdevType::GPU},
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700114 {"modem_tj", cdevType::MODEM},
Manaf Meethalavalappu Pallikunhia2c882a2022-02-25 01:14:32 +0530115 {"modem_lte_dsc", cdevType::MODEM},
116 {"modem_nr_dsc", cdevType::MODEM},
117 {"modem_nr_scg_dsc", cdevType::MODEM},
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700118 {"cdsp", cdevType::NPU},
119 {"cdsp_hw", cdevType::NPU},
120 {"battery", cdevType::BATTERY},
congyinga66894c2024-01-05 10:41:12 +0800121 {"fan-max31760", cdevType::FAN},
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700122};
123
124ThermalCommon::ThermalCommon()
125{
126 LOG(DEBUG) << "Entering " << __func__;
127 ncpus = (int)sysconf(_SC_NPROCESSORS_CONF);
128 if (ncpus < 1)
129 LOG(ERROR) << "Error retrieving number of cores";
130}
131
132static int writeToFile(std::string_view path, std::string data)
133{
134 std::fstream outFile;
135
136 outFile.open(std::string(path).c_str(),
137 std::fstream::binary | std::fstream::out);
138 if (outFile.is_open()) {
139 LOG(DEBUG) << "writing: "<< data << " in path:" << path
140 << std::endl;
141 outFile << data;
142 outFile.close();
143 return data.length();
144 }
145
146 LOG(ERROR) << "Error opening file: "<< path << std::endl;
147 return -1;
148}
149
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800150static int readLineFromFile(std::string_view path, std::string& out)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700151{
152 char *fgets_ret;
153 FILE *fd;
154 int rv;
155 char buf[MAX_LENGTH];
156
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800157 out.clear();
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700158
159 fd = fopen(std::string(path).c_str(), "r");
160 if (fd == NULL) {
161 LOG(ERROR) << "Path:" << std::string(path) << " file open error.err:"
162 << strerror(errno) << std::endl;
163 return errno;
164 }
165
166 fgets_ret = fgets(buf, MAX_LENGTH, fd);
167 if (NULL != fgets_ret) {
168 rv = (int)strlen(buf);
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800169 out.append(buf, rv);
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700170 } else {
171 rv = ferror(fd);
172 }
173
174 fclose(fd);
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800175 out.erase(std::remove(out.begin(), out.end(), '\n'), out.end());
176 LOG(DEBUG) << "Path:" << std::string(path) << " Val:" << out << std::endl;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700177
178 return rv;
179}
180
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800181int ThermalCommon::readFromFile(std::string_view path, std::string& out)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700182{
183 return readLineFromFile(path, out);
184}
185
186static int get_tzn(std::string sensor_name)
187{
188 DIR *tdir = NULL;
189 struct dirent *tdirent = NULL;
190 int found = -1;
191 int tzn = 0;
192 char name[MAX_PATH] = {0};
193 char cwd[MAX_PATH] = {0};
194 int ret = 0;
195
196 if (!getcwd(cwd, sizeof(cwd)))
197 return found;
198
199 /* Change dir to read the entries. Doesnt work otherwise */
200 ret = chdir(THERMAL_SYSFS);
201 if (ret) {
202 LOG(ERROR) << "Unable to change to " << THERMAL_SYSFS << std::endl;
203 return found;
204 }
205 tdir = opendir(THERMAL_SYSFS);
206 if (!tdir) {
207 LOG(ERROR) << "Unable to open " << THERMAL_SYSFS << std::endl;
208 return found;
209 }
210
211 while ((tdirent = readdir(tdir))) {
212 std::string buf;
213
214 if (strncmp(tdirent->d_name, TZ_DIR_NAME,
215 strlen(TZ_DIR_NAME)) != 0)
216 continue;
217
218 snprintf(name, MAX_PATH, "%s%s/%s", THERMAL_SYSFS,
219 tdirent->d_name, TZ_TYPE);
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800220 ret = readLineFromFile(std::string_view(name), buf);
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700221 if (ret <= 0) {
222 LOG(ERROR) <<
223 "get_tzn: sensor name read error for tz:" <<
224 tdirent->d_name << std::endl;
225 continue;
226 }
227 if (!strncmp(buf.c_str(), sensor_name.c_str(),
228 sensor_name.length())) {
229 found = 1;
230 break;
231 }
232 }
233
234 if (found == 1) {
235 sscanf(tdirent->d_name, TZ_DIR_FMT, &tzn);
236 LOG(DEBUG) << "Sensor: " << sensor_name <<
237 " found at tz: " << tzn << std::endl;
238 found = tzn;
239 }
240
241 closedir(tdir);
242 /* Restore current working dir */
243 ret = chdir(cwd);
244
245 return found;
246}
247
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800248int ThermalCommon::initialize_sensor(struct target_therm_cfg& cfg, int sens_idx)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700249{
250 struct therm_sensor sensor;
251 int idx = 0;
252
253 sensor.tzn = get_tzn(cfg.sensor_list[sens_idx]);
254 if (sensor.tzn < 0) {
255 LOG(ERROR) << "No thermal zone for sensor: " <<
256 cfg.sensor_list[sens_idx] << ", ret:" <<
257 sensor.tzn << std::endl;
258 return -1;
259 }
260 if (cfg.type == TemperatureType::CPU)
261 sensor.thresh.name = sensor.t.name =
262 std::string("CPU") + std::to_string(sens_idx);
263 else
264 sensor.thresh.name = sensor.t.name = cfg.label;
265
266 if (cfg.type == TemperatureType::BCL_PERCENTAGE)
267 sensor.mulFactor = 1;
268 else
269 sensor.mulFactor = 1000;
270
271 sensor.sensor_name = cfg.sensor_list[sens_idx];
272 sensor.positiveThresh = cfg.positive_thresh_ramp;
273 sensor.lastThrottleStatus = sensor.t.throttlingStatus =
274 ThrottlingSeverity::NONE;
275 sensor.thresh.type = sensor.t.type = cfg.type;
Priyansh Jaind670d792022-07-20 15:51:13 +0530276 sensor.throt_severity = cfg.throt_severity;
Ram Chandrasekarf61c6142020-08-31 15:05:42 -0700277 for (idx = 0; idx <= (size_t)ThrottlingSeverity::SHUTDOWN; idx++) {
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700278 sensor.thresh.hotThrottlingThresholds.push_back(UNKNOWN_TEMPERATURE);
279 sensor.thresh.coldThrottlingThresholds.push_back(UNKNOWN_TEMPERATURE);
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700280 }
281
282 if (cfg.throt_thresh != 0 && cfg.positive_thresh_ramp)
Priyansh Jaind670d792022-07-20 15:51:13 +0530283 sensor.thresh.hotThrottlingThresholds[(size_t)sensor.throt_severity] =
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700284 cfg.throt_thresh / (float)sensor.mulFactor;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700285 else if (cfg.throt_thresh != 0 && !cfg.positive_thresh_ramp)
Priyansh Jaind670d792022-07-20 15:51:13 +0530286 sensor.thresh.coldThrottlingThresholds[(size_t)sensor.throt_severity] =
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700287 cfg.throt_thresh / (float)sensor.mulFactor;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700288
289 if (cfg.shutdwn_thresh != 0 && cfg.positive_thresh_ramp)
Ram Chandrasekarf61c6142020-08-31 15:05:42 -0700290 sensor.thresh.hotThrottlingThresholds[(size_t)ThrottlingSeverity::SHUTDOWN] =
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700291 cfg.shutdwn_thresh / (float)sensor.mulFactor;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700292 else if (cfg.shutdwn_thresh != 0 && !cfg.positive_thresh_ramp)
Ram Chandrasekarf61c6142020-08-31 15:05:42 -0700293 sensor.thresh.coldThrottlingThresholds[(size_t)ThrottlingSeverity::SHUTDOWN] =
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700294 cfg.shutdwn_thresh / (float)sensor.mulFactor;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700295
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700296 sens.push_back(sensor);
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700297
298 return 0;
299}
300
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800301int ThermalCommon::initializeCpuSensor(struct target_therm_cfg& cpu_cfg)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700302{
303 int cpu = 0;
304
305 for (;cpu < ncpus; cpu++) {
306 if (initialize_sensor(cpu_cfg, cpu) < 0)
307 return -1;
308 }
309
310 return 0;
311}
312
Priyansh Jainc5ea5602024-08-12 11:18:21 +0530313int ThermalCommon::initNewThermalZone(struct target_therm_cfg& cfg)
314{
315
316 if (cfg.type == TemperatureType::CPU)
317 initializeCpuSensor(cfg);
318 else
319 initialize_sensor(cfg, 0);
320
321 return 1;
322}
323
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800324int ThermalCommon::initThermalZones(std::vector<struct target_therm_cfg>& cfg)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700325{
326 std::vector<struct target_therm_cfg>::iterator it;
327
328 if (cfg.empty()) {
329 LOG(ERROR) << std::string(__func__) +":Invalid input";
330 return -1;
331 }
332
333 for (it = cfg.begin(); it != cfg.end(); it++)
334 {
Priyansh Jainc5ea5602024-08-12 11:18:21 +0530335 if (it->type == TemperatureType::CPU)
336 initializeCpuSensor(*it);
337 else
338 initialize_sensor(*it, 0);
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700339 }
340
341 return sens.size();
342}
343
344int ThermalCommon::initCdev()
345{
346 DIR *tdir = NULL;
347 struct dirent *tdirent = NULL;
348 int cdevn = 0;
349 char name[MAX_PATH] = {0};
350 char cwd[MAX_PATH] = {0};
351 int ret = 0;
352
353 if (!getcwd(cwd, sizeof(cwd)))
354 return 0;
355
356 /* Change dir to read the entries. Doesnt work otherwise */
357 ret = chdir(THERMAL_SYSFS);
358 if (ret) {
359 LOG(ERROR) << "Unable to change to " << THERMAL_SYSFS << std::endl;
360 return 0;
361 }
362 tdir = opendir(THERMAL_SYSFS);
363 if (!tdir) {
364 LOG(ERROR) << "Unable to open " << THERMAL_SYSFS << std::endl;
365 return 0;
366 }
367
368 while ((tdirent = readdir(tdir))) {
369 std::string buf;
370 struct dirent *tzdirent;
371 std::unordered_map<std::string, cdevType>::iterator it;
372 struct therm_cdev cdevInst;
373
374 if (strncmp(tdirent->d_name, CDEV_DIR_NAME,
375 strlen(CDEV_DIR_NAME)) != 0)
376 continue;
377
378 snprintf(name, MAX_PATH, "%s%s/%s", THERMAL_SYSFS,
379 tdirent->d_name, TZ_TYPE);
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800380 ret = readLineFromFile(std::string_view(name), buf);
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700381 if (ret <= 0) {
382 LOG(ERROR) <<
383 "init_cdev: cdev type read error for cdev:" <<
384 tdirent->d_name << std::endl;
385 }
386 it = cdev_map.find(buf);
387 if (it == cdev_map.end())
388 continue;
389 sscanf(tdirent->d_name, CDEV_DIR_FMT, &cdevn);
390 LOG(DEBUG) << "cdev: " << it->first <<
391 " found at cdev number: " << cdevn << std::endl;
392 cdevInst.c.name = it->first;
393 cdevInst.c.type = it->second;
394 cdevInst.cdevn = cdevn;
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800395 read_cdev_state(cdevInst);
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700396 cdev.push_back(cdevInst);
397 }
398
399 closedir(tdir);
400 /* Restore current working dir */
401 ret = chdir(cwd);
402
403 return cdev.size();
404}
405
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800406int ThermalCommon::read_cdev_state(struct therm_cdev& cdev)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700407{
408 char file_name[MAX_PATH];
409 std::string buf;
Ram Chandrasekar9e1b3262021-07-29 15:41:00 -0700410 int ret = 0, ct = 0;
411 bool read_ok = false;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700412
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700413 snprintf(file_name, sizeof(file_name), CDEV_CUR_STATE_PATH,
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800414 cdev.cdevn);
Ram Chandrasekar9e1b3262021-07-29 15:41:00 -0700415 do {
416 ret = readLineFromFile(std::string(file_name), buf);
417 if (ret <= 0) {
418 LOG(ERROR) << "Cdev state read error:"<< ret <<
419 " for cdev: " << cdev.c.name;
420 return -1;
421 }
422 try {
423 cdev.c.value = std::stoi(buf, nullptr, 0);
424 read_ok = true;
425 }
426 catch (std::exception &err) {
427 LOG(ERROR) << "Cdev read stoi error:" << err.what()
428 << " cdev:" << cdev.c.name << " ID:"
429 << cdev.cdevn << " buf:" << buf <<
430 std::endl;
431 }
432 ct++;
433 } while (!read_ok && ct < RETRY_CT);
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800434 LOG(DEBUG) << "cdev Name:" << cdev.c.name << ". state:" <<
435 cdev.c.value << std::endl;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700436
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800437 return cdev.c.value;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700438}
439
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800440int ThermalCommon::estimateSeverity(struct therm_sensor& sensor)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700441{
442 int idx = 0;
443 ThrottlingSeverity severity = ThrottlingSeverity::NONE;
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800444 float temp = sensor.t.value;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700445
Ram Chandrasekarf61c6142020-08-31 15:05:42 -0700446 for (idx = (int)ThrottlingSeverity::SHUTDOWN; idx >= 0; idx--) {
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800447 /* If a particular threshold is hit already, check if the
448 * hysteresis is cleared before changing the severity */
449 if (idx == (int)sensor.t.throttlingStatus) {
450 if ((sensor.positiveThresh &&
451 !isnan(sensor.thresh.hotThrottlingThresholds[idx]) &&
452 temp >=
453 (sensor.thresh.hotThrottlingThresholds[idx] -
454 DEFAULT_HYSTERESIS / sensor.mulFactor)) ||
455 (!sensor.positiveThresh &&
456 !isnan(sensor.thresh.coldThrottlingThresholds[idx]) &&
457 temp <=
458 (sensor.thresh.coldThrottlingThresholds[idx] +
459 DEFAULT_HYSTERESIS / sensor.mulFactor)))
460 break;
461 continue;
462 }
463 if ((sensor.positiveThresh &&
464 !isnan(sensor.thresh.hotThrottlingThresholds[idx]) &&
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700465 temp >=
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800466 sensor.thresh.hotThrottlingThresholds[idx]) ||
467 (!sensor.positiveThresh &&
468 !isnan(sensor.thresh.coldThrottlingThresholds[idx]) &&
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700469 temp <=
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800470 sensor.thresh.coldThrottlingThresholds[idx]))
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700471 break;
472 }
473 if (idx >= 0)
Ram Chandrasekarf61c6142020-08-31 15:05:42 -0700474 severity = (ThrottlingSeverity)(idx);
Rashid Zafare10611c2023-06-21 12:09:36 -0700475 LOG(DEBUG) << "Sensor Name:" << sensor.t.name << "temp: " <<
Ram Chandrasekar9e1b3262021-07-29 15:41:00 -0700476 temp << ". prev severity:" <<
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800477 (int)sensor.lastThrottleStatus << ". cur severity:" <<
478 (int)sensor.t.throttlingStatus << " New severity:" <<
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700479 (int)severity << std::endl;
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800480 if (severity == sensor.t.throttlingStatus)
481 return -1;
482 sensor.lastThrottleStatus = sensor.t.throttlingStatus;
483 sensor.t.throttlingStatus = severity;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700484
Priyansh Jaine98d33d2025-05-09 08:53:44 +0530485 if (sensor.sensor_name == "disp-lea-left" || sensor.sensor_name == "disp-lea-right") {
486 ThrottlingSeverity cur_severity =
487 std::max(left_display_throttle_severity, right_display_throttle_severity);
488 if (sensor.sensor_name == "disp-lea-left") {
489 left_display_throttle_severity = severity;
490 } else if (sensor.sensor_name == "disp-lea-right") {
491 right_display_throttle_severity = severity;
492 }
493
494 ThrottlingSeverity new_severity =
495 std::max(left_display_throttle_severity, right_display_throttle_severity);
496
497 LOG(DEBUG) << "Current display severity: " << (int)cur_severity
498 << " New severity L: " << (int)left_display_throttle_severity
499 << " New severity R: " << (int)right_display_throttle_severity
500 << " New severity combined: " << (int)new_severity << std::endl;
501
502 if (cur_severity != new_severity) {
503 return (int)new_severity;
504 } else {
505 return -1;
506 }
507 }
508
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800509 return (int)severity;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700510}
511
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800512int ThermalCommon::read_temperature(struct therm_sensor& sensor)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700513{
514 char file_name[MAX_PATH];
515 float temp;
516 std::string buf;
Ram Chandrasekar9e1b3262021-07-29 15:41:00 -0700517 int ret = 0, ct = 0;
518 bool read_ok = false;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700519
Ram Chandrasekar9e1b3262021-07-29 15:41:00 -0700520 do {
521 snprintf(file_name, sizeof(file_name), TEMPERATURE_FILE_FORMAT,
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800522 sensor.tzn);
Ram Chandrasekar9e1b3262021-07-29 15:41:00 -0700523 ret = readLineFromFile(std::string(file_name), buf);
524 if (ret <= 0) {
525 LOG(ERROR) << "Temperature read error:"<< ret <<
526 " for sensor " << sensor.t.name;
527 return -1;
528 }
529 try {
530 sensor.t.value = (float)std::stoi(buf, nullptr, 0) /
531 (float)sensor.mulFactor;
532 read_ok = true;
533 }
534 catch (std::exception &err) {
535 LOG(ERROR) << "Temperature buf stoi error: "
536 << err.what()
537 << " buf:" << buf << " sensor:"
538 << sensor.t.name << " TZ:" <<
539 sensor.tzn << std::endl;
540 }
541 ct++;
542 } while (!read_ok && ct < RETRY_CT);
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800543 LOG(DEBUG) << "Sensor Name:" << sensor.t.name << ". Temperature:" <<
544 (float)sensor.t.value << std::endl;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700545
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800546 return ret;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700547}
548
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800549void ThermalCommon::initThreshold(struct therm_sensor& sensor)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700550{
551 char file_name[MAX_PATH] = "";
552 std::string buf;
553 int ret = 0, idx;
554 ThrottlingSeverity severity = ThrottlingSeverity::NONE;
555 int next_trip, curr_trip, hyst_temp = 0;
556
557 LOG(DEBUG) << "Entering " <<__func__;
558 if (!sensor.positiveThresh) {
559 LOG(ERROR) << "negative temperature ramp for sensor:"<<
560 sensor.t.name;
561 return;
562 }
Ram Chandrasekar14a48f52021-04-06 13:25:32 -0700563#ifndef ENABLE_THERMAL_NETLINK
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700564 snprintf(file_name, sizeof(file_name), POLICY_FILE_FORMAT,
565 sensor.tzn);
Ram Chandrasekardbc52fc2020-11-17 13:57:40 -0800566 ret = readLineFromFile(std::string(file_name), buf);
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700567 if (ret <= 0) {
568 LOG(ERROR) << "Policy read error:"<< ret <<
569 " for sensor " << sensor.t.name;
570 return;
571 }
572 if (buf != std::string(USER_SPACE_POLICY)) {
573 LOG(ERROR) << "Policy error:"<< buf << " sensor:" <<
574 sensor.t.name << std::endl;
575 return;
576 }
Ram Chandrasekar14a48f52021-04-06 13:25:32 -0700577#endif
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700578 next_trip = UNKNOWN_TEMPERATURE;
Ram Chandrasekarf61c6142020-08-31 15:05:42 -0700579 for (idx = 0;idx <= (int)ThrottlingSeverity::SHUTDOWN; idx++) {
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700580 if (isnan(sensor.thresh.hotThrottlingThresholds[idx])
Ram Chandrasekarf61c6142020-08-31 15:05:42 -0700581 || idx <= (int)sensor.t.throttlingStatus)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700582 continue;
583
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700584 next_trip = sensor.thresh.hotThrottlingThresholds[idx] *
585 sensor.mulFactor;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700586 break;
587 }
588
589 if (!isnan(next_trip)) {
590 LOG(DEBUG) << "Sensor: " << sensor.t.name << " high trip:"
591 << next_trip << std::endl;
592 snprintf(file_name, sizeof(file_name), TRIP_FILE_FORMAT,
593 sensor.tzn);
594 writeToFile(std::string_view(file_name), std::to_string(next_trip));
595 }
596 if (sensor.t.throttlingStatus != ThrottlingSeverity::NONE) {
597 curr_trip = sensor.thresh.hotThrottlingThresholds[
Ram Chandrasekarf61c6142020-08-31 15:05:42 -0700598 (int)sensor.t.throttlingStatus]
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700599 * sensor.mulFactor;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700600 if (!isnan(next_trip))
601 hyst_temp = (next_trip - curr_trip) + DEFAULT_HYSTERESIS;
602 else
603 hyst_temp = DEFAULT_HYSTERESIS;
604 LOG(DEBUG) << "Sensor: " << sensor.t.name << " hysteresis:"
605 << hyst_temp << std::endl;
606 snprintf(file_name, sizeof(file_name), HYST_FILE_FORMAT,
607 sensor.tzn);
608 writeToFile(std::string_view(file_name), std::to_string(hyst_temp));
609 }
610
611 return;
612}
613
Manaf Meethalavalappu Pallikunhi4d2b7142024-08-22 01:18:41 +0530614int ThermalCommon::findLimitProfile(void)
615{
616 char file_name[MAX_PATH];
617 std::string buf;
618 int trip = 1, lp = -1;
619 int ct = 0, ret = 0;
620 bool read_ok = false;
621 int tzn = get_tzn(LIMIT_PROFILE_SD_TZ);
622 if (tzn < 0) {
623 LOG(ERROR) <<" Not able to get tz id for "
624 << LIMIT_PROFILE_SD_TZ << std::endl;
625 return -1;
626 }
627
628 do {
629 snprintf(file_name, sizeof(file_name), TRIP_TYPE_FILE_FORMAT,
630 tzn, trip);
631 ret = readFromFile(std::string_view(file_name), buf);
632 if (ret <= 0) {
633 LOG(ERROR) <<" Not able to read trip type trip: "
634 << trip << std::endl;
635 return -1;
636 }
637 if (strncmp(buf.c_str(), LIMIT_PROFILE_TRIP_TYPE,
638 strlen(LIMIT_PROFILE_TRIP_TYPE))) {
639 trip++;
640 if (trip > LIMIT_PROFILE_TRIP_MAX)
641 return -1;
642 continue;
643 }
644
645 snprintf(file_name, sizeof(file_name), TRIP_N_FILE_FORMAT,
646 tzn, trip);
647 do {
648 ret = readFromFile(std::string_view(file_name), buf);
649 if (ret <= 0) {
650 LOG(ERROR) <<" Not able to read trip temp, id: "
651 << trip << std::endl;
652 return -1;
653 }
654 try {
655 lp = std::stoi(buf, nullptr, 0);
656 read_ok = true;
657 }
658 catch (std::exception &err) {
659 LOG(ERROR) <<"limits profile stoi err:"
660 << err.what() << " buf:" << buf;
661 }
662 ct++;
663 } while (!read_ok && ct < RETRY_CT);
664
665 lp = lp == LIMIT_PROFILE_1_SD_TEMP ? 1 : 0;
666
667 break;
668 } while (1);
669
670 return lp;
671}
672
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700673}// namespace thermal
674}// namespace hardware
675}// namespace android
676}// namespace aidl