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"
247a98c19aSPatrick Venture #include "pid/zone.hpp"
257a98c19aSPatrick Venture #include "pid/zone_interface.hpp"
2631058fd3SJosh Lehan #include "util.hpp"
27da4a5dd1SPatrick Venture 
28a83a3eccSPatrick Venture #include <sdbusplus/bus.hpp>
29a83a3eccSPatrick Venture 
30b748b68cSPatrick Venture #include <cstdint>
315c7cc545SPatrick Venture #include <iostream>
325c7cc545SPatrick Venture #include <memory>
33b748b68cSPatrick Venture #include <string>
345c7cc545SPatrick Venture #include <unordered_map>
35b748b68cSPatrick Venture #include <vector>
365c7cc545SPatrick Venture 
37a076487aSPatrick Venture namespace pid_control
38a076487aSPatrick Venture {
39a076487aSPatrick Venture 
405c7cc545SPatrick Venture static constexpr bool deferSignals = true;
415c7cc545SPatrick Venture static constexpr auto objectPath = "/xyz/openbmc_project/settings/fanctrl/zone";
425c7cc545SPatrick Venture 
getControlPath(int64_t zone)437af157b1SPatrick Venture static std::string getControlPath(int64_t zone)
445c7cc545SPatrick Venture {
455c7cc545SPatrick Venture     return std::string(objectPath) + std::to_string(zone);
465c7cc545SPatrick Venture }
475c7cc545SPatrick Venture 
getPidControlPath(int64_t zone,std::string pidname)487c6d35d5Sykchiu static std::string getPidControlPath(int64_t zone, std::string pidname)
497c6d35d5Sykchiu {
507c6d35d5Sykchiu     return std::string(objectPath) + std::to_string(zone) + "/" + pidname;
517c6d35d5Sykchiu }
527c6d35d5Sykchiu 
535301aae3SJohnathan Mantey std::unordered_map<int64_t, std::shared_ptr<ZoneInterface>>
buildZones(const std::map<int64_t,conf::PIDConf> & zonePids,std::map<int64_t,conf::ZoneConfig> & zoneConfigs,SensorManager & mgr,sdbusplus::bus_t & modeControlBus)547e3f8abeSPatrick Venture     buildZones(const std::map<int64_t, conf::PIDConf>& zonePids,
551df9e879SPatrick Venture                std::map<int64_t, conf::ZoneConfig>& zoneConfigs,
56b228bc30SPatrick Williams                SensorManager& mgr, sdbusplus::bus_t& modeControlBus)
575c7cc545SPatrick Venture {
585301aae3SJohnathan Mantey     std::unordered_map<int64_t, std::shared_ptr<ZoneInterface>> zones;
595c7cc545SPatrick Venture 
602a50eda8SPatrick Venture     for (const auto& [zoneId, pidConfig] : zonePids)
615c7cc545SPatrick Venture     {
625c7cc545SPatrick Venture         /* The above shouldn't be necessary but is, and I am having trouble
635c7cc545SPatrick Venture          * locating my notes on why.  If I recall correctly it was casting it
645c7cc545SPatrick Venture          * down to a byte in at least some cases causing weird behaviors.
655c7cc545SPatrick Venture          */
665c7cc545SPatrick Venture         auto zoneConf = zoneConfigs.find(zoneId);
675c7cc545SPatrick Venture         if (zoneConf == zoneConfigs.end())
685c7cc545SPatrick Venture         {
695c7cc545SPatrick Venture             /* The Zone doesn't have a configuration, bail. */
705c7cc545SPatrick Venture             static constexpr auto err =
715c7cc545SPatrick Venture                 "Bailing during load, missing Zone Configuration";
725c7cc545SPatrick Venture             std::cerr << err << std::endl;
735c7cc545SPatrick Venture             throw std::runtime_error(err);
745c7cc545SPatrick Venture         }
755c7cc545SPatrick Venture 
765301aae3SJohnathan Mantey         auto zone = std::make_shared<DbusPidZone>(
773484bedaSJames Feist             zoneId, zoneConf->second.minThermalOutput,
780e8fc398SBonnie Lo             zoneConf->second.failsafePercent, zoneConf->second.cycleTime, mgr,
79*9788963cSDelphine CC Chiu             modeControlBus, getControlPath(zoneId).c_str(), deferSignals,
80*9788963cSDelphine CC Chiu             zoneConf->second.accumulateSetPoint);
815c7cc545SPatrick Venture 
820bbeaf84SPatrick Venture         std::cerr << "Zone Id: " << zone->getZoneID() << "\n";
835c7cc545SPatrick Venture 
845c7cc545SPatrick Venture         // For each PID create a Controller and a Sensor.
852a50eda8SPatrick Venture         for (const auto& [name, info] : pidConfig)
865c7cc545SPatrick Venture         {
8731058fd3SJosh Lehan             std::vector<pid_control::conf::SensorInput> inputs;
885c7cc545SPatrick Venture             std::cerr << "PID name: " << name << "\n";
895c7cc545SPatrick Venture 
905c7cc545SPatrick Venture             /*
915c7cc545SPatrick Venture              * TODO(venture): Need to check if input is known to the
925c7cc545SPatrick Venture              * SensorManager.
935c7cc545SPatrick Venture              */
942a50eda8SPatrick Venture             if (info.type == "fan")
955c7cc545SPatrick Venture             {
962a50eda8SPatrick Venture                 for (const auto& i : info.inputs)
975c7cc545SPatrick Venture                 {
985c7cc545SPatrick Venture                     inputs.push_back(i);
993f0f7bc3SJosh Lehan                     zone->addFanInput(i.name, i.missingIsAcceptable);
1005c7cc545SPatrick Venture                 }
1015c7cc545SPatrick Venture 
10231058fd3SJosh Lehan                 auto pid = FanController::createFanPid(
10331058fd3SJosh Lehan                     zone.get(), name, splitNames(inputs), info.pidInfo);
1045c7cc545SPatrick Venture                 zone->addFanPID(std::move(pid));
1059fe3a3c7Sykchiu                 zone->addPidFailSafePercent(name, info.failSafePercent);
1065c7cc545SPatrick Venture             }
1072a50eda8SPatrick Venture             else if (isThermalType(info.type))
1085c7cc545SPatrick Venture             {
1092a50eda8SPatrick Venture                 for (const auto& i : info.inputs)
1105c7cc545SPatrick Venture                 {
1115c7cc545SPatrick Venture                     inputs.push_back(i);
1123f0f7bc3SJosh Lehan                     zone->addThermalInput(i.name, i.missingIsAcceptable);
1135c7cc545SPatrick Venture                 }
1145c7cc545SPatrick Venture 
115563a356fSPatrick Venture                 auto pid = ThermalController::createThermalPid(
1162a50eda8SPatrick Venture                     zone.get(), name, inputs, info.setpoint, info.pidInfo,
1172a50eda8SPatrick Venture                     getThermalType(info.type));
11822c257abSJames Feist 
1195c7cc545SPatrick Venture                 zone->addThermalPID(std::move(pid));
12037180062SHarvey Wu                 zone->addPidControlProcess(
12137180062SHarvey Wu                     name, info.type, info.setpoint, modeControlBus,
12237180062SHarvey Wu                     getPidControlPath(zoneId, name), deferSignals);
1239fe3a3c7Sykchiu                 zone->addPidFailSafePercent(name, info.failSafePercent);
1245c7cc545SPatrick Venture             }
1252a50eda8SPatrick Venture             else if (info.type == "stepwise")
12622c257abSJames Feist             {
1272a50eda8SPatrick Venture                 for (const auto& i : info.inputs)
12822c257abSJames Feist                 {
12922c257abSJames Feist                     inputs.push_back(i);
1303f0f7bc3SJosh Lehan                     zone->addThermalInput(i.name, i.missingIsAcceptable);
13122c257abSJames Feist                 }
132563a356fSPatrick Venture                 auto stepwise = StepwiseController::createStepwiseController(
13331058fd3SJosh Lehan                     zone.get(), name, splitNames(inputs), info.stepwiseInfo);
13422c257abSJames Feist                 zone->addThermalPID(std::move(stepwise));
13537180062SHarvey Wu                 zone->addPidControlProcess(
13637180062SHarvey Wu                     name, info.type, info.setpoint, modeControlBus,
13737180062SHarvey Wu                     getPidControlPath(zoneId, name), deferSignals);
1389fe3a3c7Sykchiu                 zone->addPidFailSafePercent(name, info.failSafePercent);
13922c257abSJames Feist             }
1405c7cc545SPatrick Venture 
1415c7cc545SPatrick Venture             std::cerr << "inputs: ";
1424a2dc4d8SPatrick Venture             for (const auto& i : inputs)
1435c7cc545SPatrick Venture             {
14431058fd3SJosh Lehan                 std::cerr << i.name;
14531058fd3SJosh Lehan                 if (i.convertTempToMargin)
14631058fd3SJosh Lehan                 {
14731058fd3SJosh Lehan                     std::cerr << "[" << i.convertMarginZero << "]";
14831058fd3SJosh Lehan                 }
1493f0f7bc3SJosh Lehan                 if (i.missingIsAcceptable)
1503f0f7bc3SJosh Lehan                 {
1513f0f7bc3SJosh Lehan                     std::cerr << "?";
1523f0f7bc3SJosh Lehan                 }
15331058fd3SJosh Lehan                 std::cerr << ", ";
1545c7cc545SPatrick Venture             }
1555c7cc545SPatrick Venture             std::cerr << "\n";
1565c7cc545SPatrick Venture         }
1575c7cc545SPatrick Venture 
1585c7cc545SPatrick Venture         zone->emit_object_added();
1595c7cc545SPatrick Venture         zones[zoneId] = std::move(zone);
1605c7cc545SPatrick Venture     }
1615c7cc545SPatrick Venture 
1625c7cc545SPatrick Venture     return zones;
1635c7cc545SPatrick Venture }
164a076487aSPatrick Venture 
165a076487aSPatrick Venture } // namespace pid_control
166