15c7cc545SPatrick Venture /** 25c7cc545SPatrick Venture * Copyright 2017 Google Inc. 35c7cc545SPatrick Venture * 45c7cc545SPatrick Venture * Licensed under the Apache License, Version 2.0 (the "License"); 55c7cc545SPatrick Venture * you may not use this file except in compliance with the License. 65c7cc545SPatrick Venture * You may obtain a copy of the License at 75c7cc545SPatrick Venture * 85c7cc545SPatrick Venture * http://www.apache.org/licenses/LICENSE-2.0 95c7cc545SPatrick Venture * 105c7cc545SPatrick Venture * Unless required by applicable law or agreed to in writing, software 115c7cc545SPatrick Venture * distributed under the License is distributed on an "AS IS" BASIS, 125c7cc545SPatrick Venture * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135c7cc545SPatrick Venture * See the License for the specific language governing permissions and 145c7cc545SPatrick Venture * limitations under the License. 155c7cc545SPatrick Venture */ 165c7cc545SPatrick Venture 175c7cc545SPatrick Venture #include "pid/builder.hpp" 185c7cc545SPatrick Venture 19da4a5dd1SPatrick Venture #include "conf.hpp" 2022c257abSJames Feist #include "pid/controller.hpp" 21da4a5dd1SPatrick Venture #include "pid/fancontroller.hpp" 2222c257abSJames Feist #include "pid/stepwisecontroller.hpp" 23da4a5dd1SPatrick Venture #include "pid/thermalcontroller.hpp" 24da4a5dd1SPatrick Venture 255c7cc545SPatrick Venture #include <iostream> 265c7cc545SPatrick Venture #include <memory> 275c7cc545SPatrick Venture #include <sdbusplus/bus.hpp> 285c7cc545SPatrick Venture #include <unordered_map> 295c7cc545SPatrick Venture 305c7cc545SPatrick Venture static constexpr bool deferSignals = true; 315c7cc545SPatrick Venture static constexpr auto objectPath = "/xyz/openbmc_project/settings/fanctrl/zone"; 325c7cc545SPatrick Venture 335c7cc545SPatrick Venture static std::string GetControlPath(int64_t zone) 345c7cc545SPatrick Venture { 355c7cc545SPatrick Venture return std::string(objectPath) + std::to_string(zone); 365c7cc545SPatrick Venture } 375c7cc545SPatrick Venture 38da4a5dd1SPatrick Venture std::unordered_map<int64_t, std::unique_ptr<PIDZone>> 39da4a5dd1SPatrick Venture BuildZones(std::map<int64_t, PIDConf>& zonePids, 40da4a5dd1SPatrick Venture std::map<int64_t, struct zone>& zoneConfigs, SensorManager& mgr, 415c7cc545SPatrick Venture sdbusplus::bus::bus& modeControlBus) 425c7cc545SPatrick Venture { 435c7cc545SPatrick Venture std::unordered_map<int64_t, std::unique_ptr<PIDZone>> zones; 445c7cc545SPatrick Venture 45*4a2dc4d8SPatrick Venture for (const auto& zi : zonePids) 465c7cc545SPatrick Venture { 475c7cc545SPatrick Venture auto zoneId = static_cast<int64_t>(zi.first); 485c7cc545SPatrick Venture /* The above shouldn't be necessary but is, and I am having trouble 495c7cc545SPatrick Venture * locating my notes on why. If I recall correctly it was casting it 505c7cc545SPatrick Venture * down to a byte in at least some cases causing weird behaviors. 515c7cc545SPatrick Venture */ 525c7cc545SPatrick Venture 535c7cc545SPatrick Venture auto zoneConf = zoneConfigs.find(zoneId); 545c7cc545SPatrick Venture if (zoneConf == zoneConfigs.end()) 555c7cc545SPatrick Venture { 565c7cc545SPatrick Venture /* The Zone doesn't have a configuration, bail. */ 575c7cc545SPatrick Venture static constexpr auto err = 585c7cc545SPatrick Venture "Bailing during load, missing Zone Configuration"; 595c7cc545SPatrick Venture std::cerr << err << std::endl; 605c7cc545SPatrick Venture throw std::runtime_error(err); 615c7cc545SPatrick Venture } 625c7cc545SPatrick Venture 63*4a2dc4d8SPatrick Venture const PIDConf& PIDConfig = zi.second; 645c7cc545SPatrick Venture 655c7cc545SPatrick Venture auto zone = std::make_unique<PIDZone>( 66da4a5dd1SPatrick Venture zoneId, zoneConf->second.minthermalrpm, 67da4a5dd1SPatrick Venture zoneConf->second.failsafepercent, mgr, modeControlBus, 68da4a5dd1SPatrick Venture GetControlPath(zi.first).c_str(), deferSignals); 695c7cc545SPatrick Venture 705c7cc545SPatrick Venture std::cerr << "Zone Id: " << zone->getZoneId() << "\n"; 715c7cc545SPatrick Venture 725c7cc545SPatrick Venture // For each PID create a Controller and a Sensor. 73*4a2dc4d8SPatrick Venture for (const auto& pit : PIDConfig) 745c7cc545SPatrick Venture { 755c7cc545SPatrick Venture std::vector<std::string> inputs; 765c7cc545SPatrick Venture std::string name = pit.first; 77*4a2dc4d8SPatrick Venture const struct controller_info* info = &pit.second; 785c7cc545SPatrick Venture 795c7cc545SPatrick Venture std::cerr << "PID name: " << name << "\n"; 805c7cc545SPatrick Venture 815c7cc545SPatrick Venture /* 825c7cc545SPatrick Venture * TODO(venture): Need to check if input is known to the 835c7cc545SPatrick Venture * SensorManager. 845c7cc545SPatrick Venture */ 855c7cc545SPatrick Venture if (info->type == "fan") 865c7cc545SPatrick Venture { 87*4a2dc4d8SPatrick Venture for (const auto& i : info->inputs) 885c7cc545SPatrick Venture { 895c7cc545SPatrick Venture inputs.push_back(i); 905c7cc545SPatrick Venture zone->addFanInput(i); 915c7cc545SPatrick Venture } 925c7cc545SPatrick Venture 93da4a5dd1SPatrick Venture auto pid = FanController::CreateFanPid(zone.get(), name, inputs, 9422c257abSJames Feist info->pidInfo); 955c7cc545SPatrick Venture zone->addFanPID(std::move(pid)); 965c7cc545SPatrick Venture } 975c7cc545SPatrick Venture else if (info->type == "temp" || info->type == "margin") 985c7cc545SPatrick Venture { 99*4a2dc4d8SPatrick Venture for (const auto& i : info->inputs) 1005c7cc545SPatrick Venture { 1015c7cc545SPatrick Venture inputs.push_back(i); 1025c7cc545SPatrick Venture zone->addThermalInput(i); 1035c7cc545SPatrick Venture } 1045c7cc545SPatrick Venture 1055c7cc545SPatrick Venture auto pid = ThermalController::CreateThermalPid( 10622c257abSJames Feist zone.get(), name, inputs, info->setpoint, info->pidInfo); 10722c257abSJames Feist 1085c7cc545SPatrick Venture zone->addThermalPID(std::move(pid)); 1095c7cc545SPatrick Venture } 11022c257abSJames Feist else if (info->type == "stepwise") 11122c257abSJames Feist { 112*4a2dc4d8SPatrick Venture for (const auto& i : info->inputs) 11322c257abSJames Feist { 11422c257abSJames Feist inputs.push_back(i); 11522c257abSJames Feist zone->addThermalInput(i); 11622c257abSJames Feist } 11722c257abSJames Feist auto stepwise = StepwiseController::CreateStepwiseController( 11822c257abSJames Feist zone.get(), name, inputs, info->stepwiseInfo); 11922c257abSJames Feist zone->addThermalPID(std::move(stepwise)); 12022c257abSJames Feist } 1215c7cc545SPatrick Venture 1225c7cc545SPatrick Venture std::cerr << "inputs: "; 123*4a2dc4d8SPatrick Venture for (const auto& i : inputs) 1245c7cc545SPatrick Venture { 1255c7cc545SPatrick Venture std::cerr << i << ", "; 1265c7cc545SPatrick Venture } 1275c7cc545SPatrick Venture std::cerr << "\n"; 1285c7cc545SPatrick Venture } 1295c7cc545SPatrick Venture 1305c7cc545SPatrick Venture zone->emit_object_added(); 1315c7cc545SPatrick Venture zones[zoneId] = std::move(zone); 1325c7cc545SPatrick Venture } 1335c7cc545SPatrick Venture 1345c7cc545SPatrick Venture return zones; 1355c7cc545SPatrick Venture } 136