blob: 6de7bcc768717a46cc85b3080c0028d181df9eff [file] [log] [blame]
Alexander Hansen46a755f2025-10-27 16:31:08 +01001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright 2017 Google Inc
Patrick Venture5c7cc542018-06-11 14:29:38 -07003
4#include "pid/builder.hpp"
5
Patrick Ventureda4a5dd2018-08-31 09:42:48 -07006#include "conf.hpp"
Ed Tanousf8b6e552025-06-27 13:27:50 -07007#include "manager.hpp"
James Feist22c257a2018-08-31 14:07:12 -07008#include "pid/controller.hpp"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -07009#include "pid/fancontroller.hpp"
James Feist22c257a2018-08-31 14:07:12 -070010#include "pid/stepwisecontroller.hpp"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070011#include "pid/thermalcontroller.hpp"
Patrick Venture7a98c192020-08-12 08:35:16 -070012#include "pid/zone.hpp"
13#include "pid/zone_interface.hpp"
Josh Lehan31058fd2023-01-13 11:06:16 -080014#include "util.hpp"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070015
Patrick Venturea83a3ec2020-08-04 09:52:05 -070016#include <sdbusplus/bus.hpp>
17
Patrick Ventureb748b682020-08-16 08:33:53 -070018#include <cstdint>
Patrick Venture5c7cc542018-06-11 14:29:38 -070019#include <iostream>
Ed Tanousf8b6e552025-06-27 13:27:50 -070020#include <map>
Patrick Venture5c7cc542018-06-11 14:29:38 -070021#include <memory>
Ed Tanousf8b6e552025-06-27 13:27:50 -070022#include <stdexcept>
Patrick Ventureb748b682020-08-16 08:33:53 -070023#include <string>
Patrick Venture5c7cc542018-06-11 14:29:38 -070024#include <unordered_map>
Ed Tanousf8b6e552025-06-27 13:27:50 -070025#include <utility>
Patrick Ventureb748b682020-08-16 08:33:53 -070026#include <vector>
Patrick Venture5c7cc542018-06-11 14:29:38 -070027
Patrick Venturea0764872020-08-08 07:48:43 -070028namespace pid_control
29{
30
Patrick Venture5c7cc542018-06-11 14:29:38 -070031static constexpr bool deferSignals = true;
32static constexpr auto objectPath = "/xyz/openbmc_project/settings/fanctrl/zone";
33
Patrick Venture7af157b2018-10-30 11:24:40 -070034static std::string getControlPath(int64_t zone)
Patrick Venture5c7cc542018-06-11 14:29:38 -070035{
36 return std::string(objectPath) + std::to_string(zone);
37}
38
Ed Tanousd2768c52025-06-26 11:42:57 -070039static std::string getPidControlPath(int64_t zone, const std::string& pidname)
ykchiu7c6d35d2023-05-10 17:01:46 +080040{
41 return std::string(objectPath) + std::to_string(zone) + "/" + pidname;
42}
43
Patrick Williams19300272025-02-01 08:22:48 -050044std::unordered_map<int64_t, std::shared_ptr<ZoneInterface>> buildZones(
45 const std::map<int64_t, conf::PIDConf>& zonePids,
46 std::map<int64_t, conf::ZoneConfig>& zoneConfigs, SensorManager& mgr,
47 sdbusplus::bus_t& modeControlBus)
Patrick Venture5c7cc542018-06-11 14:29:38 -070048{
Johnathan Mantey5301aae2020-09-28 11:06:58 -070049 std::unordered_map<int64_t, std::shared_ptr<ZoneInterface>> zones;
Patrick Venture5c7cc542018-06-11 14:29:38 -070050
Patrick Venture2a50eda2020-08-16 08:26:35 -070051 for (const auto& [zoneId, pidConfig] : zonePids)
Patrick Venture5c7cc542018-06-11 14:29:38 -070052 {
Patrick Venture5c7cc542018-06-11 14:29:38 -070053 /* The above shouldn't be necessary but is, and I am having trouble
54 * locating my notes on why. If I recall correctly it was casting it
55 * down to a byte in at least some cases causing weird behaviors.
56 */
Patrick Venture5c7cc542018-06-11 14:29:38 -070057 auto zoneConf = zoneConfigs.find(zoneId);
58 if (zoneConf == zoneConfigs.end())
59 {
60 /* The Zone doesn't have a configuration, bail. */
61 static constexpr auto err =
62 "Bailing during load, missing Zone Configuration";
63 std::cerr << err << std::endl;
64 throw std::runtime_error(err);
65 }
66
Johnathan Mantey5301aae2020-09-28 11:06:58 -070067 auto zone = std::make_shared<DbusPidZone>(
James Feist3484bed2019-02-25 13:28:18 -080068 zoneId, zoneConf->second.minThermalOutput,
Bonnie Lo0e8fc392022-10-05 10:20:55 +080069 zoneConf->second.failsafePercent, zoneConf->second.cycleTime, mgr,
Delphine CC Chiu97889632023-11-06 11:32:46 +080070 modeControlBus, getControlPath(zoneId).c_str(), deferSignals,
71 zoneConf->second.accumulateSetPoint);
Patrick Venture5c7cc542018-06-11 14:29:38 -070072
Patrick Venture0bbeaf82018-10-30 18:50:31 -070073 std::cerr << "Zone Id: " << zone->getZoneID() << "\n";
Patrick Venture5c7cc542018-06-11 14:29:38 -070074
75 // For each PID create a Controller and a Sensor.
Patrick Venture2a50eda2020-08-16 08:26:35 -070076 for (const auto& [name, info] : pidConfig)
Patrick Venture5c7cc542018-06-11 14:29:38 -070077 {
Josh Lehan31058fd2023-01-13 11:06:16 -080078 std::vector<pid_control::conf::SensorInput> inputs;
Patrick Venture5c7cc542018-06-11 14:29:38 -070079 std::cerr << "PID name: " << name << "\n";
80
81 /*
82 * TODO(venture): Need to check if input is known to the
83 * SensorManager.
84 */
Patrick Venture2a50eda2020-08-16 08:26:35 -070085 if (info.type == "fan")
Patrick Venture5c7cc542018-06-11 14:29:38 -070086 {
Patrick Venture2a50eda2020-08-16 08:26:35 -070087 for (const auto& i : info.inputs)
Patrick Venture5c7cc542018-06-11 14:29:38 -070088 {
89 inputs.push_back(i);
Josh Lehan3f0f7bc2023-02-13 01:45:29 -080090 zone->addFanInput(i.name, i.missingIsAcceptable);
Patrick Venture5c7cc542018-06-11 14:29:38 -070091 }
92
Josh Lehan31058fd2023-01-13 11:06:16 -080093 auto pid = FanController::createFanPid(
94 zone.get(), name, splitNames(inputs), info.pidInfo);
Patrick Venture5c7cc542018-06-11 14:29:38 -070095 zone->addFanPID(std::move(pid));
Harvey Wu92f9f3c2023-11-07 09:23:35 +080096 zone->addPidFailSafePercent(splitNames(inputs),
97 info.failSafePercent);
Patrick Venture5c7cc542018-06-11 14:29:38 -070098 }
Patrick Venture2a50eda2020-08-16 08:26:35 -070099 else if (isThermalType(info.type))
Patrick Venture5c7cc542018-06-11 14:29:38 -0700100 {
Patrick Venture2a50eda2020-08-16 08:26:35 -0700101 for (const auto& i : info.inputs)
Patrick Venture5c7cc542018-06-11 14:29:38 -0700102 {
103 inputs.push_back(i);
Josh Lehan3f0f7bc2023-02-13 01:45:29 -0800104 zone->addThermalInput(i.name, i.missingIsAcceptable);
Patrick Venture5c7cc542018-06-11 14:29:38 -0700105 }
106
Patrick Venture563a3562018-10-30 09:31:26 -0700107 auto pid = ThermalController::createThermalPid(
Patrick Venture2a50eda2020-08-16 08:26:35 -0700108 zone.get(), name, inputs, info.setpoint, info.pidInfo,
109 getThermalType(info.type));
James Feist22c257a2018-08-31 14:07:12 -0700110
Patrick Venture5c7cc542018-06-11 14:29:38 -0700111 zone->addThermalPID(std::move(pid));
Harvey Wu37180062023-10-02 09:42:50 +0800112 zone->addPidControlProcess(
113 name, info.type, info.setpoint, modeControlBus,
114 getPidControlPath(zoneId, name), deferSignals);
Harvey Wu92f9f3c2023-11-07 09:23:35 +0800115 zone->addPidFailSafePercent(splitNames(inputs),
116 info.failSafePercent);
Patrick Venture5c7cc542018-06-11 14:29:38 -0700117 }
Patrick Venture2a50eda2020-08-16 08:26:35 -0700118 else if (info.type == "stepwise")
James Feist22c257a2018-08-31 14:07:12 -0700119 {
Patrick Venture2a50eda2020-08-16 08:26:35 -0700120 for (const auto& i : info.inputs)
James Feist22c257a2018-08-31 14:07:12 -0700121 {
122 inputs.push_back(i);
Josh Lehan3f0f7bc2023-02-13 01:45:29 -0800123 zone->addThermalInput(i.name, i.missingIsAcceptable);
James Feist22c257a2018-08-31 14:07:12 -0700124 }
Patrick Venture563a3562018-10-30 09:31:26 -0700125 auto stepwise = StepwiseController::createStepwiseController(
Josh Lehan31058fd2023-01-13 11:06:16 -0800126 zone.get(), name, splitNames(inputs), info.stepwiseInfo);
James Feist22c257a2018-08-31 14:07:12 -0700127 zone->addThermalPID(std::move(stepwise));
Harvey Wu37180062023-10-02 09:42:50 +0800128 zone->addPidControlProcess(
129 name, info.type, info.setpoint, modeControlBus,
130 getPidControlPath(zoneId, name), deferSignals);
Harvey Wu92f9f3c2023-11-07 09:23:35 +0800131 zone->addPidFailSafePercent(splitNames(inputs),
132 info.failSafePercent);
James Feist22c257a2018-08-31 14:07:12 -0700133 }
Patrick Venture5c7cc542018-06-11 14:29:38 -0700134
135 std::cerr << "inputs: ";
Patrick Venture4a2dc4d2018-10-23 09:02:55 -0700136 for (const auto& i : inputs)
Patrick Venture5c7cc542018-06-11 14:29:38 -0700137 {
Josh Lehan31058fd2023-01-13 11:06:16 -0800138 std::cerr << i.name;
139 if (i.convertTempToMargin)
140 {
141 std::cerr << "[" << i.convertMarginZero << "]";
142 }
Josh Lehan3f0f7bc2023-02-13 01:45:29 -0800143 if (i.missingIsAcceptable)
144 {
145 std::cerr << "?";
146 }
Josh Lehan31058fd2023-01-13 11:06:16 -0800147 std::cerr << ", ";
Patrick Venture5c7cc542018-06-11 14:29:38 -0700148 }
149 std::cerr << "\n";
150 }
151
152 zone->emit_object_added();
153 zones[zoneId] = std::move(zone);
154 }
155
156 return zones;
157}
Patrick Venturea0764872020-08-08 07:48:43 -0700158
159} // namespace pid_control