thermal-hal: Add support to check limit profile for volcano

Add support to check limit profile based on thermal zone configuration
and update different limit profile settings for volcano.

Change-Id: I483ca40810db4dcb60e8bbb77182f29bc4226614
diff --git a/thermalCommon.cpp b/thermalCommon.cpp
index 1bbe2cf..5ecd8de 100644
--- a/thermalCommon.cpp
+++ b/thermalCommon.cpp
@@ -53,6 +53,8 @@
 #define POLICY_FILE_FORMAT	"/sys/class/thermal/thermal_zone%d/policy"
 #define TRIP_FILE_FORMAT	"/sys/class/thermal/thermal_zone%d/trip_point_1_temp"
 #define HYST_FILE_FORMAT	"/sys/class/thermal/thermal_zone%d/trip_point_1_hyst"
+#define TRIP_TYPE_FILE_FORMAT	"/sys/class/thermal/thermal_zone%d/trip_point_%d_type"
+#define TRIP_N_FILE_FORMAT	"/sys/class/thermal/thermal_zone%d/trip_point_%d_temp"
 #define USER_SPACE_POLICY	"user_space"
 #define TZ_TYPE			"type"
 #define CDEV_DIR_NAME		"cooling_device"
@@ -60,6 +62,11 @@
 #define CDEV_CUR_STATE_PATH	"/sys/class/thermal/cooling_device%d/cur_state"
 #define CPU_USAGE_FILE		"/proc/stat"
 #define CPU_ONLINE_FILE_FORMAT	"/sys/devices/system/cpu/cpu%d/online"
+#define LIMIT_PROFILE_1_SD_TEMP	118000
+#define LIMIT_PROFILE_TRIP_TYPE	"hot"
+#define LIMIT_PROFILE_SD_TZ	"aoss-0"
+#define LIMIT_PROFILE_TRIP_MAX	11
+
 
 namespace aidl {
 namespace android {
@@ -572,6 +579,65 @@
 	return;
 }
 
+int ThermalCommon::findLimitProfile(void)
+{
+	char file_name[MAX_PATH];
+	std::string buf;
+	int trip = 1, lp = -1;
+	int ct = 0, ret = 0;
+	bool read_ok = false;
+	int tzn = get_tzn(LIMIT_PROFILE_SD_TZ);
+	if (tzn < 0) {
+		LOG(ERROR) <<" Not able to get tz id for "
+		         << LIMIT_PROFILE_SD_TZ << std::endl;
+		return -1;
+	}
+
+	do {
+		snprintf(file_name, sizeof(file_name), TRIP_TYPE_FILE_FORMAT,
+			tzn, trip);
+		ret = readFromFile(std::string_view(file_name), buf);
+		if (ret <= 0) {
+			LOG(ERROR) <<" Not able to read trip type trip: "
+					<< trip << std::endl;
+			return -1;
+		}
+		if (strncmp(buf.c_str(), LIMIT_PROFILE_TRIP_TYPE,
+					strlen(LIMIT_PROFILE_TRIP_TYPE))) {
+			trip++;
+			if (trip > LIMIT_PROFILE_TRIP_MAX)
+				return -1;
+			continue;
+		}
+
+		snprintf(file_name, sizeof(file_name), TRIP_N_FILE_FORMAT,
+				tzn, trip);
+		do {
+			ret = readFromFile(std::string_view(file_name), buf);
+			if (ret <= 0) {
+				LOG(ERROR) <<" Not able to read trip temp, id: "
+					<< trip << std::endl;
+				return -1;
+			}
+			try {
+				lp = std::stoi(buf, nullptr, 0);
+				read_ok = true;
+			}
+			catch (std::exception &err) {
+				LOG(ERROR) <<"limits profile stoi err:"
+					<< err.what() << " buf:" << buf;
+			}
+			ct++;
+		} while (!read_ok && ct < RETRY_CT);
+
+		lp = lp == LIMIT_PROFILE_1_SD_TEMP ? 1 : 0;
+
+		break;
+	} while (1);
+
+	return lp;
+}
+
 }// namespace thermal
 }// namespace hardware
 }// namespace android
diff --git a/thermalCommon.h b/thermalCommon.h
index cff388b..ef96179 100644
--- a/thermalCommon.h
+++ b/thermalCommon.h
@@ -53,6 +53,7 @@
 		int read_cdev_state(struct therm_cdev& cdev);
 		int read_temperature(struct therm_sensor& sensor);
 		int estimateSeverity(struct therm_sensor& sensor);
+		int findLimitProfile(void);
 
 		std::vector<struct therm_sensor> fetch_sensor_list()
 		{
diff --git a/thermalConfig.cpp b/thermalConfig.cpp
index 60b3c60..0658286 100644
--- a/thermalConfig.cpp
+++ b/thermalConfig.cpp
@@ -1606,6 +1606,57 @@
 		},
 	};
 
+	std::vector<struct target_therm_cfg> volcano_profile1 = {
+		{
+			TemperatureType::CPU,
+			cpu_sensors_volcano,
+			"",
+			105000,
+			118000,
+			true,
+		},
+		{
+			TemperatureType::GPU,
+			{ "gpuss-0" },
+			"GPU0",
+			105000,
+			118000,
+			true,
+		},
+		{
+			TemperatureType::GPU,
+			{ "gpuss-1" },
+			"GPU1",
+			105000,
+			118000,
+			true,
+		},
+		{
+			TemperatureType::NPU,
+			{ "nsphvx-0" },
+			"nsp0",
+			105000,
+			118000,
+			true,
+		},
+		{
+			TemperatureType::NPU,
+			{ "nsphmx-0" },
+			"nsp2",
+			105000,
+			118000,
+			true,
+		},
+		{
+			TemperatureType::NPU,
+			{ "nsphmx-1" },
+			"nsp3",
+			105000,
+			118000,
+			true,
+		},
+	};
+
 	std::vector<struct target_therm_cfg>  volcano_specific = {
 		{
 			TemperatureType::SKIN,
@@ -1815,8 +1866,8 @@
 		{652, niobe_common}, // Matrix_4k
 		{636, volcano_common}, //milos
 		{640, volcano_common}, //milos6
-		{657, volcano_common}, //milos IOT with modem
-		{658, volcano_common}, //milos IOT
+		{657, volcano_specific}, //milos IOT with modem
+		{658, volcano_specific}, //milos IOT
 		{549, anorak_common},
 		{649, anorak_common}, // Halliday Pro
 	};
@@ -1850,8 +1901,6 @@
 		{652, niobe_specific}, // Matrix_4k
 		{636, volcano_specific}, //milos
 		{640, volcano_specific}, //milos6
-		{657, volcano_specific}, //milos IOT with modem
-		{658, volcano_specific}, //milos IOT
 		{549, anorak_specific},
 		{649, anorak_specific}, // Halliday Pro
 	};
@@ -1866,18 +1915,39 @@
 		{405, true},
 	};
 
+	const std::unordered_multimap<int, std::pair<int, std::vector<struct target_therm_cfg>>>
+	msm_limit_profile_specific = {
+		{657, std::make_pair(0, volcano_common)},
+		{657, std::make_pair(1, volcano_profile1)},
+		{658, std::make_pair(0, volcano_common)},
+		{658, std::make_pair(1, volcano_profile1)},
+	};
+
 	std::vector<struct target_therm_cfg> add_target_config(
-			int socID,
+			int socID, int lp,
 			std::vector<struct target_therm_cfg> conf)
 	{
 		std::vector<struct target_therm_cfg> targetConf;
 
-		if (msm_soc_specific.find(socID) == msm_soc_specific.end())
-			return conf;
-		targetConf = (msm_soc_specific.find(socID))->second;
+		if (msm_soc_specific.find(socID) != msm_soc_specific.end()) {
+			targetConf = (msm_soc_specific.find(socID))->second;
 
-		conf.insert(conf.end(), targetConf.begin(),
-					targetConf.end());
+			conf.insert(conf.end(), targetConf.begin(),
+						targetConf.end());
+		}
+
+		auto range = msm_limit_profile_specific.equal_range(socID);
+		auto it = range.first;
+		if (range.first != msm_limit_profile_specific.end()) {
+			for (; it != range.second; ++it) {
+				if (it->second.first != lp)
+					continue;
+				targetConf = it->second.second;
+				conf.insert(conf.end(), targetConf.begin(),targetConf.end());
+				break;
+			}
+		}
+
 		return conf;
 	}
 
@@ -1910,12 +1980,22 @@
 			LOG(ERROR) << "Invalid soc ID: " << soc_id;
 			return;
 		}
+
+		auto range = msm_limit_profile_specific.equal_range(soc_id);
+		if (range.first != msm_limit_profile_specific.end()) {
+			limitp = cmnInst.findLimitProfile();
+			if (limitp < 0) {
+				LOG(DEBUG) << "Invalid limit profile, defaulting to 0.";
+				limitp = 0;
+			}
+		}
+
 		it = msm_soc_map.find(soc_id);
 		if (it == msm_soc_map.end()) {
 			LOG(ERROR) << "No config for soc ID: " << soc_id;
 			return;
 		}
-		thermalConfig = add_target_config(soc_id, it->second);
+		thermalConfig = add_target_config(soc_id, limitp, it->second);
 		for (it_vec = thermalConfig.begin();
 				it_vec != thermalConfig.end(); it_vec++) {
 			if (it_vec->type == TemperatureType::BCL_PERCENTAGE)
diff --git a/thermalConfig.h b/thermalConfig.h
index ae74111..3a8ef1c 100644
--- a/thermalConfig.h
+++ b/thermalConfig.h
@@ -59,6 +59,7 @@
 	private:
 		std::vector<struct target_therm_cfg> thermalConfig;
 		int soc_id;
+		int limitp;
 		ThermalCommon cmnInst;
 };