1 #pragma once 2 3 #include "config.h" 4 5 #include "compatible_system_types_finder.hpp" 6 #include "device_finder.hpp" 7 #include "power_interface.hpp" 8 #include "power_sequencer_device.hpp" 9 #include "rail.hpp" 10 #include "services.hpp" 11 12 #include <gpiod.hpp> 13 #include <sdbusplus/bus.hpp> 14 #include <sdbusplus/server/object.hpp> 15 #include <sdeventplus/clock.hpp> 16 #include <sdeventplus/event.hpp> 17 #include <sdeventplus/utility/timer.hpp> 18 19 #include <chrono> 20 #include <filesystem> 21 #include <memory> 22 #include <optional> 23 #include <string> 24 #include <vector> 25 26 namespace phosphor::power::sequencer 27 { 28 29 using PowerObject = sdbusplus::server::object_t<PowerInterface>; 30 31 /** 32 * @class PowerControl 33 * This class implements GPIO control of power on / off, and monitoring of the 34 * chassis power good. 35 */ 36 class PowerControl : public PowerObject 37 { 38 public: 39 PowerControl() = delete; 40 PowerControl(const PowerControl&) = delete; 41 PowerControl& operator=(const PowerControl&) = delete; 42 PowerControl(PowerControl&&) = delete; 43 PowerControl& operator=(PowerControl&&) = delete; 44 ~PowerControl() = default; 45 46 /** 47 * Creates a controller object for power on and off. 48 * @param bus D-Bus bus object 49 * @param event event object 50 */ 51 PowerControl(sdbusplus::bus_t& bus, const sdeventplus::Event& event); 52 53 /** @copydoc PowerInterface::getPgood() */ 54 int getPgood() const override; 55 56 /** @copydoc PowerInterface::getPgoodTimeout() */ 57 int getPgoodTimeout() const override; 58 59 /** @copydoc PowerInterface::getState() */ 60 int getState() const override; 61 62 /** @copydoc PowerInterface::setPgoodTimeout() */ 63 void setPgoodTimeout(int timeout) override; 64 65 /** @copydoc PowerInterface::setState() */ 66 void setState(int state) override; 67 68 /** @copydoc PowerInterface::setPowerSupplyError() */ 69 void setPowerSupplyError(const std::string& error) override; 70 71 /** 72 * Callback that is called when a list of compatible system types is found. 73 * 74 * @param types Compatible system types for the current system ordered from 75 * most to least specific 76 */ 77 void compatibleSystemTypesFound(const std::vector<std::string>& types); 78 79 /** 80 * Callback that is called when a power sequencer device is found. 81 * 82 * @param properties Properties of device that was found 83 */ 84 void deviceFound(const DeviceProperties& properties); 85 86 private: 87 /** 88 * The D-Bus bus object 89 */ 90 sdbusplus::bus_t& bus; 91 92 /** 93 * System services like hardware presence and the journal. 94 */ 95 BMCServices services; 96 97 /** 98 * Object that finds the compatible system types for the current system. 99 */ 100 std::unique_ptr<util::CompatibleSystemTypesFinder> compatSysTypesFinder; 101 102 /** 103 * Compatible system types for the current system ordered from most to least 104 * specific. 105 */ 106 std::vector<std::string> compatibleSystemTypes; 107 108 /** 109 * Object that finds the power sequencer device in the system. 110 */ 111 std::unique_ptr<DeviceFinder> deviceFinder; 112 113 /** 114 * Power sequencer device properties. 115 */ 116 std::optional<DeviceProperties> deviceProperties; 117 118 /** 119 * Power sequencer device that enables and monitors the voltage rails. 120 */ 121 std::unique_ptr<PowerSequencerDevice> device; 122 123 /** 124 * Indicates if a failure has already been found. Cleared at power on. 125 */ 126 bool failureFound{false}; 127 128 /** 129 * Indicates if a state transition is taking place 130 */ 131 bool inStateTransition{false}; 132 133 /** 134 * Minimum time from cold start to power on constant 135 */ 136 static constexpr std::chrono::seconds minimumColdStartTime{15}; 137 138 /** 139 * Minimum time from power off to power on constant 140 */ 141 static constexpr std::chrono::seconds minimumPowerOffTime{25}; 142 143 /** 144 * Power good 145 */ 146 int pgood{0}; 147 148 /** 149 * GPIO line object for chassis power good 150 */ 151 gpiod::line pgoodLine; 152 153 /** 154 * Power good timeout constant 155 */ 156 static constexpr std::chrono::seconds pgoodTimeout{PGOOD_TIMEOUT}; 157 158 /** 159 * Point in time at which power good timeout will take place 160 */ 161 std::chrono::time_point<std::chrono::steady_clock> pgoodTimeoutTime; 162 163 /** 164 * Timer to wait after pgood failure. This is to allow the power supplies 165 * and other hardware time to complete failure processing. 166 */ 167 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pgoodWaitTimer; 168 169 /** 170 * Poll interval constant 171 */ 172 static constexpr std::chrono::milliseconds pollInterval{3000}; 173 174 /** 175 * GPIO line object for power on / power off control 176 */ 177 gpiod::line powerControlLine; 178 179 /** 180 * Point in time at which minumum power off time will have passed 181 */ 182 std::chrono::time_point<std::chrono::steady_clock> powerOnAllowedTime; 183 184 /** 185 * Power supply error. Cleared at power on. 186 */ 187 std::string powerSupplyError; 188 189 /** 190 * Power state 191 */ 192 int state{0}; 193 194 /** 195 * Power good timeout 196 */ 197 std::chrono::seconds timeout{pgoodTimeout}; 198 199 /** 200 * Timer to poll the pgood 201 */ 202 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer; 203 204 /** 205 * Callback to begin failure processing after observing pgood failure wait 206 */ 207 void onFailureCallback(); 208 209 /** 210 * Begin pgood failure processing 211 * 212 * @param wasTimeOut Indicates whether failure state was determined by 213 * timing out 214 */ 215 void onFailure(bool wasTimeOut); 216 217 /** 218 * Polling method for monitoring the system power good 219 */ 220 void pollPgood(); 221 222 /** 223 * Set up GPIOs 224 */ 225 void setUpGpio(); 226 227 /** 228 * Loads the JSON configuration file and creates the power sequencer device 229 * object. 230 * 231 * Does nothing if the compatible system types or device properties have not 232 * been found yet. These are obtained from D-Bus. The order in which they 233 * are found and the time to find them varies. 234 */ 235 void loadConfigFileAndCreateDevice(); 236 237 /** 238 * Finds the JSON configuration file for the current system based on the 239 * compatible system types. 240 * 241 * Does nothing if the compatible system types have not been found yet. 242 * 243 * @return absolute path to the config file, or empty path if file not found 244 */ 245 std::filesystem::path findConfigFile(); 246 247 /** 248 * Parses the specified JSON configuration file. 249 * 250 * Returns the resulting vector of Rail objects in the output parameter. 251 * 252 * @param configFile Absolute path to the config file 253 * @param rails Rail objects within the config file 254 * @return true if file was parsed successfully, false otherwise 255 */ 256 bool parseConfigFile(const std::filesystem::path& configFile, 257 std::vector<std::unique_ptr<Rail>>& rails); 258 259 /** 260 * Creates the power sequencer device object based on the device properties. 261 * 262 * Does nothing if the device properties have not been found yet. 263 * 264 * @param rails Voltage rails that are enabled and monitored by the device 265 */ 266 void createDevice(std::vector<std::unique_ptr<Rail>> rails); 267 }; 268 269 } // namespace phosphor::power::sequencer 270