1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "thermal_interface_impl.h" 17094332d3Sopenharmony_ci 18094332d3Sopenharmony_ci#include <thread> 19094332d3Sopenharmony_ci#include <memory> 20094332d3Sopenharmony_ci#include <hdf_base.h> 21094332d3Sopenharmony_ci#include "thermal_hdf_config.h" 22094332d3Sopenharmony_ci#include "thermal_hdf_timer.h" 23094332d3Sopenharmony_ci#include "thermal_simulation_node.h" 24094332d3Sopenharmony_ci#include "thermal_device_mitigation.h" 25094332d3Sopenharmony_ci#include "thermal_zone_manager.h" 26094332d3Sopenharmony_ci#include "thermal_log.h" 27094332d3Sopenharmony_ci#ifdef HAS_THERMAL_CONFIG_POLICY_PART 28094332d3Sopenharmony_ci#include "config_policy_utils.h" 29094332d3Sopenharmony_ci#endif 30094332d3Sopenharmony_ci 31094332d3Sopenharmony_cinamespace OHOS { 32094332d3Sopenharmony_cinamespace HDI { 33094332d3Sopenharmony_cinamespace Thermal { 34094332d3Sopenharmony_cinamespace V1_1 { 35094332d3Sopenharmony_cinamespace { 36094332d3Sopenharmony_ci 37094332d3Sopenharmony_ciconst std::string HDI_XML_PATH = "etc/thermal_config/thermal_hdi_config.xml"; 38094332d3Sopenharmony_ciconst std::string VENDOR_HDI_XML_PATH = "/vendor/etc/thermal_config/thermal_hdi_config.xml"; 39094332d3Sopenharmony_cibool g_isHdiStart = false; 40094332d3Sopenharmony_ci} 41094332d3Sopenharmony_cistatic sptr<IThermalCallback> theramalCb_ = nullptr; 42094332d3Sopenharmony_cistatic std::shared_ptr<HdfThermalCallbackInfo> callbackInfo_ = nullptr; 43094332d3Sopenharmony_cistatic std::shared_ptr<ThermalHdfTimer> hdfTimer_ = nullptr; 44094332d3Sopenharmony_cistatic std::shared_ptr<ThermalSimulationNode> simulation_ = nullptr; 45094332d3Sopenharmony_cistatic std::shared_ptr<ThermalDeviceMitigation> mitigation_ = nullptr; 46094332d3Sopenharmony_cistatic std::shared_ptr<ThermalZoneManager> thermalZoneMgr_ = nullptr; 47094332d3Sopenharmony_ci 48094332d3Sopenharmony_ciextern "C" IThermalInterface *ThermalInterfaceImplGetInstance(void) 49094332d3Sopenharmony_ci{ 50094332d3Sopenharmony_ci return new (std::nothrow) ThermalInterfaceImpl(); 51094332d3Sopenharmony_ci} 52094332d3Sopenharmony_ci 53094332d3Sopenharmony_ciThermalInterfaceImpl::ThermalInterfaceImpl() 54094332d3Sopenharmony_ci{ 55094332d3Sopenharmony_ci Init(); 56094332d3Sopenharmony_ci} 57094332d3Sopenharmony_ci 58094332d3Sopenharmony_ciint32_t ThermalInterfaceImpl::Init() 59094332d3Sopenharmony_ci{ 60094332d3Sopenharmony_ci bool parseConfigSuc = false; 61094332d3Sopenharmony_ci int32_t ret; 62094332d3Sopenharmony_ci#ifdef HAS_THERMAL_CONFIG_POLICY_PART 63094332d3Sopenharmony_ci char buf[MAX_PATH_LEN]; 64094332d3Sopenharmony_ci char* path = GetOneCfgFile(HDI_XML_PATH.c_str(), buf, MAX_PATH_LEN); 65094332d3Sopenharmony_ci if (path != nullptr && *path != '\0') { 66094332d3Sopenharmony_ci ret = ThermalHdfConfig::GetInstance().ThermalHDIConfigInit(path); 67094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 68094332d3Sopenharmony_ci THERMAL_HILOGE(COMP_HDI, "parse err pliocy thermal hdi XML"); 69094332d3Sopenharmony_ci return HDF_FAILURE; 70094332d3Sopenharmony_ci } 71094332d3Sopenharmony_ci parseConfigSuc = true; 72094332d3Sopenharmony_ci } 73094332d3Sopenharmony_ci#endif 74094332d3Sopenharmony_ci 75094332d3Sopenharmony_ci if (!parseConfigSuc) { 76094332d3Sopenharmony_ci ret = ThermalHdfConfig::GetInstance().ThermalHDIConfigInit(VENDOR_HDI_XML_PATH); 77094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 78094332d3Sopenharmony_ci THERMAL_HILOGE(COMP_HDI, "failed to init XML, ret: %{public}d", ret); 79094332d3Sopenharmony_ci return HDF_FAILURE; 80094332d3Sopenharmony_ci } 81094332d3Sopenharmony_ci } 82094332d3Sopenharmony_ci 83094332d3Sopenharmony_ci if (simulation_ == nullptr) { 84094332d3Sopenharmony_ci simulation_ = std::make_shared<ThermalSimulationNode>(); 85094332d3Sopenharmony_ci } 86094332d3Sopenharmony_ci 87094332d3Sopenharmony_ci if (thermalZoneMgr_ == nullptr) { 88094332d3Sopenharmony_ci thermalZoneMgr_ = std::make_shared<ThermalZoneManager>(); 89094332d3Sopenharmony_ci } 90094332d3Sopenharmony_ci 91094332d3Sopenharmony_ci if (mitigation_ == nullptr) { 92094332d3Sopenharmony_ci mitigation_ = std::make_shared<ThermalDeviceMitigation>(); 93094332d3Sopenharmony_ci } 94094332d3Sopenharmony_ci 95094332d3Sopenharmony_ci if (hdfTimer_ == nullptr) { 96094332d3Sopenharmony_ci hdfTimer_ = std::make_shared<ThermalHdfTimer>(simulation_, thermalZoneMgr_); 97094332d3Sopenharmony_ci hdfTimer_->SetSimluationFlag(); 98094332d3Sopenharmony_ci } 99094332d3Sopenharmony_ci 100094332d3Sopenharmony_ci ret = simulation_->NodeInit(); 101094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 102094332d3Sopenharmony_ci return HDF_FAILURE; 103094332d3Sopenharmony_ci } 104094332d3Sopenharmony_ci 105094332d3Sopenharmony_ci thermalZoneMgr_->Init(); 106094332d3Sopenharmony_ci thermalZoneMgr_->CalculateMaxCd(); 107094332d3Sopenharmony_ci ret = thermalZoneMgr_->UpdateThermalZoneData(); 108094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 109094332d3Sopenharmony_ci return ret; 110094332d3Sopenharmony_ci } 111094332d3Sopenharmony_ci 112094332d3Sopenharmony_ci thermalZoneMgr_->DumpPollingInfo(); 113094332d3Sopenharmony_ci mitigation_->SetFlag(static_cast<bool>(hdfTimer_->GetSimluationFlag())); 114094332d3Sopenharmony_ci return HDF_SUCCESS; 115094332d3Sopenharmony_ci} 116094332d3Sopenharmony_ci 117094332d3Sopenharmony_ciint32_t ThermalInterfaceImpl::SetCpuFreq(int32_t freq) 118094332d3Sopenharmony_ci{ 119094332d3Sopenharmony_ci if (freq <= 0) { 120094332d3Sopenharmony_ci THERMAL_HILOGE(COMP_HDI, "invalid freq %{public}d", freq); 121094332d3Sopenharmony_ci return HDF_FAILURE; 122094332d3Sopenharmony_ci } 123094332d3Sopenharmony_ci if (mitigation_ != nullptr) { 124094332d3Sopenharmony_ci int32_t ret = mitigation_->CpuRequest(freq); 125094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 126094332d3Sopenharmony_ci THERMAL_HILOGE(COMP_HDI, "failed to set freq %{public}d", ret); 127094332d3Sopenharmony_ci return ret; 128094332d3Sopenharmony_ci } 129094332d3Sopenharmony_ci } 130094332d3Sopenharmony_ci return HDF_SUCCESS; 131094332d3Sopenharmony_ci} 132094332d3Sopenharmony_ci 133094332d3Sopenharmony_ciint32_t ThermalInterfaceImpl::SetGpuFreq(int32_t freq) 134094332d3Sopenharmony_ci{ 135094332d3Sopenharmony_ci if (freq <= 0) { 136094332d3Sopenharmony_ci THERMAL_HILOGE(COMP_HDI, "invalid freq %{public}d", freq); 137094332d3Sopenharmony_ci return HDF_FAILURE; 138094332d3Sopenharmony_ci } 139094332d3Sopenharmony_ci if (mitigation_ != nullptr) { 140094332d3Sopenharmony_ci int32_t ret = mitigation_->GpuRequest(freq); 141094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 142094332d3Sopenharmony_ci THERMAL_HILOGE(COMP_HDI, "failed to set freq %{public}d", ret); 143094332d3Sopenharmony_ci return ret; 144094332d3Sopenharmony_ci } 145094332d3Sopenharmony_ci } 146094332d3Sopenharmony_ci return HDF_SUCCESS; 147094332d3Sopenharmony_ci} 148094332d3Sopenharmony_ci 149094332d3Sopenharmony_ciint32_t ThermalInterfaceImpl::SetBatteryCurrent(int32_t current) 150094332d3Sopenharmony_ci{ 151094332d3Sopenharmony_ci if (current <= 0) { 152094332d3Sopenharmony_ci THERMAL_HILOGE(COMP_HDI, "invalid current %{public}d", current); 153094332d3Sopenharmony_ci return HDF_FAILURE; 154094332d3Sopenharmony_ci } 155094332d3Sopenharmony_ci if (mitigation_ != nullptr) { 156094332d3Sopenharmony_ci int32_t ret = mitigation_->ChargerRequest(current); 157094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 158094332d3Sopenharmony_ci THERMAL_HILOGE(COMP_HDI, "failed to set current %{public}d", ret); 159094332d3Sopenharmony_ci return ret; 160094332d3Sopenharmony_ci } 161094332d3Sopenharmony_ci } 162094332d3Sopenharmony_ci return HDF_SUCCESS; 163094332d3Sopenharmony_ci} 164094332d3Sopenharmony_ci 165094332d3Sopenharmony_ciint32_t ThermalInterfaceImpl::GetThermalZoneInfo(HdfThermalCallbackInfo& event) 166094332d3Sopenharmony_ci{ 167094332d3Sopenharmony_ci if (thermalZoneMgr_ != nullptr) { 168094332d3Sopenharmony_ci thermalZoneMgr_->UpdateThermalZoneData(); 169094332d3Sopenharmony_ci event.info = thermalZoneMgr_->GetCallbackInfo().info; 170094332d3Sopenharmony_ci } 171094332d3Sopenharmony_ci return HDF_SUCCESS; 172094332d3Sopenharmony_ci} 173094332d3Sopenharmony_ci 174094332d3Sopenharmony_ciint32_t ThermalInterfaceImpl::IsolateCpu(int32_t num) 175094332d3Sopenharmony_ci{ 176094332d3Sopenharmony_ci if (num <= 0) { 177094332d3Sopenharmony_ci THERMAL_HILOGE(COMP_HDI, "invalid num %{public}d", num); 178094332d3Sopenharmony_ci return HDF_FAILURE; 179094332d3Sopenharmony_ci } 180094332d3Sopenharmony_ci if (mitigation_ != nullptr) { 181094332d3Sopenharmony_ci int32_t ret = mitigation_->IsolateCpu(num); 182094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 183094332d3Sopenharmony_ci THERMAL_HILOGE(COMP_HDI, "failed to set isolate cpu num %{public}d", ret); 184094332d3Sopenharmony_ci return ret; 185094332d3Sopenharmony_ci } 186094332d3Sopenharmony_ci } 187094332d3Sopenharmony_ci return HDF_SUCCESS; 188094332d3Sopenharmony_ci} 189094332d3Sopenharmony_ci 190094332d3Sopenharmony_ciint32_t ThermalInterfaceImpl::Register(const sptr<IThermalCallback>& callbackObj) 191094332d3Sopenharmony_ci{ 192094332d3Sopenharmony_ci if (thermalZoneMgr_ == nullptr || callbackObj == nullptr) { 193094332d3Sopenharmony_ci return HDF_FAILURE; 194094332d3Sopenharmony_ci } 195094332d3Sopenharmony_ci 196094332d3Sopenharmony_ci thermalZoneMgr_->SetThermalEventCb(callbackObj); 197094332d3Sopenharmony_ci StartTimerThread(); 198094332d3Sopenharmony_ci 199094332d3Sopenharmony_ci return g_isHdiStart ? HDF_SUCCESS : HDF_FAILURE; 200094332d3Sopenharmony_ci} 201094332d3Sopenharmony_ci 202094332d3Sopenharmony_ciint32_t ThermalInterfaceImpl::Unregister() 203094332d3Sopenharmony_ci{ 204094332d3Sopenharmony_ci if (thermalZoneMgr_ == nullptr || thermalZoneMgr_->GetThermalEventCb() == nullptr) { 205094332d3Sopenharmony_ci return HDF_FAILURE; 206094332d3Sopenharmony_ci } 207094332d3Sopenharmony_ci 208094332d3Sopenharmony_ci thermalZoneMgr_->DelThermalEventCb(); 209094332d3Sopenharmony_ci return HDF_SUCCESS; 210094332d3Sopenharmony_ci} 211094332d3Sopenharmony_ci 212094332d3Sopenharmony_ciint32_t ThermalInterfaceImpl::RegisterFanCallback(const sptr<IFanCallback>& callbackObj) 213094332d3Sopenharmony_ci{ 214094332d3Sopenharmony_ci if (thermalZoneMgr_ == nullptr || callbackObj == nullptr) { 215094332d3Sopenharmony_ci return HDF_FAILURE; 216094332d3Sopenharmony_ci } 217094332d3Sopenharmony_ci 218094332d3Sopenharmony_ci thermalZoneMgr_->SetFanEventCb(callbackObj); 219094332d3Sopenharmony_ci StartTimerThread(); 220094332d3Sopenharmony_ci 221094332d3Sopenharmony_ci return g_isHdiStart ? HDF_SUCCESS : HDF_FAILURE; 222094332d3Sopenharmony_ci} 223094332d3Sopenharmony_ci 224094332d3Sopenharmony_ciint32_t ThermalInterfaceImpl::UnregisterFanCallback() 225094332d3Sopenharmony_ci{ 226094332d3Sopenharmony_ci if (thermalZoneMgr_ == nullptr || thermalZoneMgr_->GetFanEventCb() == nullptr) { 227094332d3Sopenharmony_ci return HDF_FAILURE; 228094332d3Sopenharmony_ci } 229094332d3Sopenharmony_ci 230094332d3Sopenharmony_ci thermalZoneMgr_->DelFanEventCb(); 231094332d3Sopenharmony_ci return HDF_SUCCESS; 232094332d3Sopenharmony_ci} 233094332d3Sopenharmony_ci 234094332d3Sopenharmony_civoid ThermalInterfaceImpl::StartTimerThread() 235094332d3Sopenharmony_ci{ 236094332d3Sopenharmony_ci if (hdfTimer_ == nullptr) { 237094332d3Sopenharmony_ci return; 238094332d3Sopenharmony_ci } 239094332d3Sopenharmony_ci 240094332d3Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 241094332d3Sopenharmony_ci if (!g_isHdiStart) { 242094332d3Sopenharmony_ci int32_t ret = hdfTimer_->Init(); 243094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 244094332d3Sopenharmony_ci return; 245094332d3Sopenharmony_ci } 246094332d3Sopenharmony_ci g_isHdiStart = true; 247094332d3Sopenharmony_ci } 248094332d3Sopenharmony_ci 249094332d3Sopenharmony_ci return; 250094332d3Sopenharmony_ci} 251094332d3Sopenharmony_ci 252094332d3Sopenharmony_ci} // V1_1 253094332d3Sopenharmony_ci} // Thermal 254094332d3Sopenharmony_ci} // HDI 255094332d3Sopenharmony_ci} // OHOS 256