xref: /openbmc/phosphor-power/phosphor-power-sequencer/src/power_control.hpp (revision 212543969f6e4a5908f7f2e017f59adcce7ae723)
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