blob: b4b6f951f4a37f5d488f168f7f483c28a8627845 [file] [log] [blame]
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -06001/**
2 * Copyright © 2024 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#pragma once
17
Shawn McCarney24956592024-02-19 18:58:57 -060018#include "services.hpp"
19
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060020#include <cstdint>
Shawn McCarney24956592024-02-19 18:58:57 -060021#include <map>
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060022#include <optional>
23#include <stdexcept>
24#include <string>
Shawn McCarney24956592024-02-19 18:58:57 -060025#include <vector>
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060026
27namespace phosphor::power::sequencer
28{
29
Shawn McCarneyf47a7a72024-04-18 16:59:33 -050030// Forward declarations to avoid circular dependencies
31class PowerSequencerDevice;
32
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060033/**
34 * @struct GPIO
35 *
36 * General Purpose Input/Output (GPIO) that can be read to obtain the pgood
37 * status of a voltage rail.
38 */
39struct GPIO
40{
41 /**
42 * The libgpiod line offset of the GPIO.
43 */
44 unsigned int line{0};
45
46 /**
47 * Specifies whether the GPIO is active low.
48 *
49 * If true, the GPIO value 0 indicates a true pgood status. If false, the
50 * GPIO value 1 indicates a true pgood status.
51 */
52 bool activeLow{false};
53};
54
55/**
56 * @class Rail
57 *
58 * A voltage rail that is enabled or monitored by the power sequencer device.
59 */
60class Rail
61{
62 public:
63 // Specify which compiler-generated methods we want
64 Rail() = delete;
65 Rail(const Rail&) = delete;
66 Rail(Rail&&) = delete;
67 Rail& operator=(const Rail&) = delete;
68 Rail& operator=(Rail&&) = delete;
69 ~Rail() = default;
70
71 /**
72 * Constructor.
73 *
74 * Throws an exception if any of the input parameters are invalid.
75 *
76 * @param name Unique name for the rail
77 * @param presence Optional D-Bus inventory path of a system component which
78 * must be present in order for the rail to be present
79 * @param page Optional PMBus PAGE number of the rail. Required if
Shawn McCarney9ec0d432024-02-09 18:26:00 -060080 * checkStatusVout or compareVoltageToLimit is true.
Shawn McCarney16e493a2024-01-29 14:20:32 -060081 * @param isPowerSupplyRail Specifies whether the rail is produced by a
82 * power supply
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060083 * @param checkStatusVout Specifies whether to check the value of the PMBus
84 * STATUS_VOUT command when determining the pgood
85 * status of the rail
Shawn McCarney9ec0d432024-02-09 18:26:00 -060086 * @param compareVoltageToLimit Specifies whether to compare the output
87 * voltage to the undervoltage fault limit when
88 * determining the pgood status of the rail
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060089 * @param gpio Optional GPIO to read to determine the pgood status of the
90 * rail
91 */
92 explicit Rail(const std::string& name,
93 const std::optional<std::string>& presence,
Shawn McCarney16e493a2024-01-29 14:20:32 -060094 const std::optional<uint8_t>& page, bool isPowerSupplyRail,
Shawn McCarney9ec0d432024-02-09 18:26:00 -060095 bool checkStatusVout, bool compareVoltageToLimit,
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060096 const std::optional<GPIO>& gpio) :
97 name{name},
Shawn McCarney16e493a2024-01-29 14:20:32 -060098 presence{presence}, page{page}, isPsuRail{isPowerSupplyRail},
99 checkStatusVout{checkStatusVout},
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600100 compareVoltageToLimit{compareVoltageToLimit}, gpio{gpio}
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600101 {
102 // If checking STATUS_VOUT or output voltage, verify PAGE was specified
Shawn McCarney24956592024-02-19 18:58:57 -0600103 if ((checkStatusVout || compareVoltageToLimit) && !page)
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600104 {
105 throw std::invalid_argument{"PMBus PAGE is required"};
106 }
107 }
108
109 /**
110 * Returns the unique name for the rail.
111 *
112 * @return rail name
113 */
114 const std::string& getName() const
115 {
116 return name;
117 }
118
119 /**
120 * Returns the D-Bus inventory path of a system component which must be
121 * present in order for the rail to be present.
122 *
123 * @return inventory path for presence detection
124 */
125 const std::optional<std::string>& getPresence() const
126 {
127 return presence;
128 }
129
130 /**
131 * Returns the PMBus PAGE number of the rail.
132 *
133 * @return PAGE number for rail
134 */
135 const std::optional<uint8_t>& getPage() const
136 {
137 return page;
138 }
139
140 /**
Shawn McCarney16e493a2024-01-29 14:20:32 -0600141 * Returns whether the rail is produced by a power supply.
142 *
143 * @return true if rail is produced by a power supply, false otherwise
144 */
145 bool isPowerSupplyRail() const
146 {
147 return isPsuRail;
148 }
149
150 /**
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600151 * Returns whether the value of the PMBus STATUS_VOUT command is checked
152 * when determining the pgood status of the rail.
153 *
154 * @return true if STATUS_VOUT is checked, false otherwise
155 */
156 bool getCheckStatusVout() const
157 {
158 return checkStatusVout;
159 }
160
161 /**
162 * Returns whether the output voltage should be compared to the undervoltage
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600163 * fault limit when determining the pgood status of the rail.
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600164 *
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600165 * @return true if output voltage is compared to limit, false otherwise
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600166 */
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600167 bool getCompareVoltageToLimit() const
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600168 {
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600169 return compareVoltageToLimit;
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600170 }
171
172 /**
173 * Returns the GPIO to read to determine the pgood status of the rail.
174 *
175 * @return GPIO
176 */
177 const std::optional<GPIO>& getGPIO() const
178 {
179 return gpio;
180 }
181
Shawn McCarney24956592024-02-19 18:58:57 -0600182 /**
183 * Returns whether the rail is present.
184 *
185 * Returns true if no inventory path was specified for presence detection.
186 *
187 * @param services System services like hardware presence and the journal
188 * @return true if rail is present, false otherwise
189 */
190 bool isPresent(Services& services);
191
192 /**
193 * Returns the value of the PMBus STATUS_WORD command for the rail.
194 *
195 * Reads the value from the specified device. The returned value is in
196 * host-endian order.
197 *
198 * Throws an exception if the value could not be obtained.
199 *
200 * @param device Power sequencer device that enables and monitors the rail
201 * @return STATUS_WORD value
202 */
203 uint16_t getStatusWord(PowerSequencerDevice& device);
204
205 /**
206 * Returns the value of the PMBus STATUS_VOUT command for the rail.
207 *
208 * Reads the value from the specified device.
209 *
210 * Throws an exception if the value could not be obtained.
211 *
212 * @param device Power sequencer device that enables and monitors the rail
213 * @return STATUS_VOUT value
214 */
215 uint8_t getStatusVout(PowerSequencerDevice& device);
216
217 /**
218 * Returns the value of the PMBus READ_VOUT command for the rail.
219 *
220 * Reads the value from the specified device. The returned value is in
221 * volts.
222 *
223 * Throws an exception if the value could not be obtained.
224 *
225 * @param device Power sequencer device that enables and monitors the rail
226 * @return READ_VOUT value in volts
227 */
228 double getReadVout(PowerSequencerDevice& device);
229
230 /**
231 * Returns the value of the PMBus VOUT_UV_FAULT_LIMIT command for the rail.
232 *
233 * Reads the value from the specified device. The returned value is in
234 * volts.
235 *
236 * Throws an exception if the value could not be obtained.
237 *
238 * @param device Power sequencer device that enables and monitors the rail
239 * @return VOUT_UV_FAULT_LIMIT value in volts
240 */
241 double getVoutUVFaultLimit(PowerSequencerDevice& device);
242
243 /**
244 * Returns whether a pgood (power good) fault has occurred on the rail.
245 *
246 * Throws an exception if an error occurs while trying to obtain the rail
247 * status.
248 *
249 * @param device Power sequencer device that enables and monitors the rail
250 * @param services System services like hardware presence and the journal
251 * @param gpioValues GPIO values obtained from the device (if any)
252 * @param additionalData Additional data to include in an error log if this
253 * method returns true
254 * @return true if a pgood fault was found on the rail, false otherwise
255 */
256 bool hasPgoodFault(PowerSequencerDevice& device, Services& services,
257 const std::vector<int>& gpioValues,
258 std::map<std::string, std::string>& additionalData);
259
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600260 private:
261 /**
Shawn McCarney24956592024-02-19 18:58:57 -0600262 * Verifies that a PMBus PAGE number is defined for the rail.
263 *
264 * Throws an exception if a PAGE number is not defined.
265 */
266 void verifyHasPage();
267
268 /**
269 * Returns whether the PMBus STATUS_VOUT command indicates a pgood fault
270 * has occurred on the rail.
271 *
272 * Throws an exception if an error occurs while trying to obtain the rail
273 * status.
274 *
275 * @param device Power sequencer device that enables and monitors the rail
276 * @param services System services like hardware presence and the journal
277 * @param additionalData Additional data to include in an error log if this
278 * method returns true
279 * @return true if a pgood fault was found on the rail, false otherwise
280 */
281 bool hasPgoodFaultStatusVout(
282 PowerSequencerDevice& device, Services& services,
283 std::map<std::string, std::string>& additionalData);
284
285 /**
286 * Returns whether a GPIO value indicates a pgood fault has occurred on the
287 * rail.
288 *
289 * Throws an exception if an error occurs while trying to obtain the rail
290 * status.
291 *
292 * @param device Power sequencer device that enables and monitors the rail
293 * @param gpioValues GPIO values obtained from the device (if any)
294 * @param additionalData Additional data to include in an error log if this
295 * method returns true
296 * @return true if a pgood fault was found on the rail, false otherwise
297 */
298 bool hasPgoodFaultGPIO(Services& services,
299 const std::vector<int>& gpioValues,
300 std::map<std::string, std::string>& additionalData);
301
302 /**
303 * Returns whether the output voltage is below the undervoltage limit
304 * indicating a pgood fault has occurred on the rail.
305 *
306 * Throws an exception if an error occurs while trying to obtain the rail
307 * status.
308 *
309 * @param device Power sequencer device that enables and monitors the rail
310 * @param services System services like hardware presence and the journal
311 * @param additionalData Additional data to include in an error log if this
312 * method returns true
313 * @return true if a pgood fault was found on the rail, false otherwise
314 */
315 bool hasPgoodFaultOutputVoltage(
316 PowerSequencerDevice& device, Services& services,
317 std::map<std::string, std::string>& additionalData);
318
319 /**
320 * Store pgood fault debug data in the specified additional data map.
321 *
322 * Stores data that is relevant regardless of which method was used to
323 * detect the pgood fault.
324 *
325 * @param device Power sequencer device that enables and monitors the rail
326 * @param services System services like hardware presence and the journal
327 * @param additionalData Additional data to include in an error log
328 */
329 void storePgoodFaultDebugData(
330 PowerSequencerDevice& device, Services& services,
331 std::map<std::string, std::string>& additionalData);
332
333 /**
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600334 * Unique name for the rail.
335 */
336 std::string name{};
337
338 /**
339 * D-Bus inventory path of a system component which must be present in order
340 * for the rail to be present.
341 *
342 * If not specified, the rail is assumed to always be present.
343 */
344 std::optional<std::string> presence{};
345
346 /**
347 * PMBus PAGE number of the rail.
348 */
349 std::optional<uint8_t> page{};
350
351 /**
Shawn McCarney16e493a2024-01-29 14:20:32 -0600352 * Specifies whether the rail is produced by a power supply.
353 */
354 bool isPsuRail{false};
355
356 /**
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600357 * Specifies whether to check the value of the PMBus STATUS_VOUT command
358 * when determining the pgood status of the rail.
359 *
360 * If one of the error bits is set in STATUS_VOUT, the rail pgood will be
361 * considered false.
362 */
363 bool checkStatusVout{false};
364
365 /**
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600366 * Specifies whether to compare the output voltage to the undervoltage fault
367 * limit when determining the pgood status of the rail.
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600368 *
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600369 * If the output voltage is below this limit, the rail pgood will be
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600370 * considered false.
371 *
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600372 * Uses the values of the PMBus READ_VOUT and VOUT_UV_FAULT_LIMIT commands.
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600373 */
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600374 bool compareVoltageToLimit{false};
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600375
376 /**
377 * GPIO to read to determine the pgood status of the rail.
378 */
379 std::optional<GPIO> gpio{};
380};
381
382} // namespace phosphor::power::sequencer