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,
799788963cSDelphine CC Chiu modeControlBus, getControlPath(zoneId).c_str(), deferSignals,
809788963cSDelphine 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));
105*92f9f3c8SHarvey Wu zone->addPidFailSafePercent(splitNames(inputs),
106*92f9f3c8SHarvey Wu info.failSafePercent);
1075c7cc545SPatrick Venture }
1082a50eda8SPatrick Venture else if (isThermalType(info.type))
1095c7cc545SPatrick Venture {
1102a50eda8SPatrick Venture for (const auto& i : info.inputs)
1115c7cc545SPatrick Venture {
1125c7cc545SPatrick Venture inputs.push_back(i);
1133f0f7bc3SJosh Lehan zone->addThermalInput(i.name, i.missingIsAcceptable);
1145c7cc545SPatrick Venture }
1155c7cc545SPatrick Venture
116563a356fSPatrick Venture auto pid = ThermalController::createThermalPid(
1172a50eda8SPatrick Venture zone.get(), name, inputs, info.setpoint, info.pidInfo,
1182a50eda8SPatrick Venture getThermalType(info.type));
11922c257abSJames Feist
1205c7cc545SPatrick Venture zone->addThermalPID(std::move(pid));
12137180062SHarvey Wu zone->addPidControlProcess(
12237180062SHarvey Wu name, info.type, info.setpoint, modeControlBus,
12337180062SHarvey Wu getPidControlPath(zoneId, name), deferSignals);
124*92f9f3c8SHarvey Wu zone->addPidFailSafePercent(splitNames(inputs),
125*92f9f3c8SHarvey Wu info.failSafePercent);
1265c7cc545SPatrick Venture }
1272a50eda8SPatrick Venture else if (info.type == "stepwise")
12822c257abSJames Feist {
1292a50eda8SPatrick Venture for (const auto& i : info.inputs)
13022c257abSJames Feist {
13122c257abSJames Feist inputs.push_back(i);
1323f0f7bc3SJosh Lehan zone->addThermalInput(i.name, i.missingIsAcceptable);
13322c257abSJames Feist }
134563a356fSPatrick Venture auto stepwise = StepwiseController::createStepwiseController(
13531058fd3SJosh Lehan zone.get(), name, splitNames(inputs), info.stepwiseInfo);
13622c257abSJames Feist zone->addThermalPID(std::move(stepwise));
13737180062SHarvey Wu zone->addPidControlProcess(
13837180062SHarvey Wu name, info.type, info.setpoint, modeControlBus,
13937180062SHarvey Wu getPidControlPath(zoneId, name), deferSignals);
140*92f9f3c8SHarvey Wu zone->addPidFailSafePercent(splitNames(inputs),
141*92f9f3c8SHarvey Wu info.failSafePercent);
14222c257abSJames Feist }
1435c7cc545SPatrick Venture
1445c7cc545SPatrick Venture std::cerr << "inputs: ";
1454a2dc4d8SPatrick Venture for (const auto& i : inputs)
1465c7cc545SPatrick Venture {
14731058fd3SJosh Lehan std::cerr << i.name;
14831058fd3SJosh Lehan if (i.convertTempToMargin)
14931058fd3SJosh Lehan {
15031058fd3SJosh Lehan std::cerr << "[" << i.convertMarginZero << "]";
15131058fd3SJosh Lehan }
1523f0f7bc3SJosh Lehan if (i.missingIsAcceptable)
1533f0f7bc3SJosh Lehan {
1543f0f7bc3SJosh Lehan std::cerr << "?";
1553f0f7bc3SJosh Lehan }
15631058fd3SJosh Lehan std::cerr << ", ";
1575c7cc545SPatrick Venture }
1585c7cc545SPatrick Venture std::cerr << "\n";
1595c7cc545SPatrick Venture }
1605c7cc545SPatrick Venture
1615c7cc545SPatrick Venture zone->emit_object_added();
1625c7cc545SPatrick Venture zones[zoneId] = std::move(zone);
1635c7cc545SPatrick Venture }
1645c7cc545SPatrick Venture
1655c7cc545SPatrick Venture return zones;
1665c7cc545SPatrick Venture }
167a076487aSPatrick Venture
168a076487aSPatrick Venture } // namespace pid_control
169