blob: ee331cac66afbed162480e934889b9e98acdade2 [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 McCarney24956592024-02-19 18:58:57 -0600260 /**
261 * Returns whether the PMBus STATUS_VOUT command indicates a pgood fault
262 * has occurred on the rail.
263 *
264 * Throws an exception if an error occurs while trying to obtain the rail
265 * status.
266 *
267 * @param device Power sequencer device that enables and monitors the rail
268 * @param services System services like hardware presence and the journal
269 * @param additionalData Additional data to include in an error log if this
270 * method returns true
271 * @return true if a pgood fault was found on the rail, false otherwise
272 */
273 bool hasPgoodFaultStatusVout(
274 PowerSequencerDevice& device, Services& services,
275 std::map<std::string, std::string>& additionalData);
276
277 /**
278 * Returns whether a GPIO value indicates a pgood fault has occurred on the
279 * rail.
280 *
281 * Throws an exception if an error occurs while trying to obtain the rail
282 * status.
283 *
284 * @param device Power sequencer device that enables and monitors the rail
Shawn McCarney16275832024-06-27 10:14:11 -0500285 * @param services System services like hardware presence and the journal
Shawn McCarney24956592024-02-19 18:58:57 -0600286 * @param gpioValues GPIO values obtained from the device (if any)
287 * @param additionalData Additional data to include in an error log if this
288 * method returns true
289 * @return true if a pgood fault was found on the rail, false otherwise
290 */
Shawn McCarney16275832024-06-27 10:14:11 -0500291 bool hasPgoodFaultGPIO(PowerSequencerDevice& device, Services& services,
Shawn McCarney24956592024-02-19 18:58:57 -0600292 const std::vector<int>& gpioValues,
293 std::map<std::string, std::string>& additionalData);
294
295 /**
296 * Returns whether the output voltage is below the undervoltage limit
297 * indicating a pgood fault has occurred on the rail.
298 *
299 * Throws an exception if an error occurs while trying to obtain the rail
300 * status.
301 *
302 * @param device Power sequencer device that enables and monitors the rail
303 * @param services System services like hardware presence and the journal
304 * @param additionalData Additional data to include in an error log if this
305 * method returns true
306 * @return true if a pgood fault was found on the rail, false otherwise
307 */
308 bool hasPgoodFaultOutputVoltage(
309 PowerSequencerDevice& device, Services& services,
310 std::map<std::string, std::string>& additionalData);
311
Shawn McCarney16275832024-06-27 10:14:11 -0500312 private:
313 /**
314 * Verifies that a PMBus PAGE number is defined for the rail.
315 *
316 * Throws an exception if a PAGE number is not defined.
317 */
318 void verifyHasPage();
319
Shawn McCarney24956592024-02-19 18:58:57 -0600320 /**
321 * Store pgood fault debug data in the specified additional data map.
322 *
323 * Stores data that is relevant regardless of which method was used to
324 * detect the pgood fault.
325 *
326 * @param device Power sequencer device that enables and monitors the rail
327 * @param services System services like hardware presence and the journal
328 * @param additionalData Additional data to include in an error log
329 */
330 void storePgoodFaultDebugData(
331 PowerSequencerDevice& device, Services& services,
332 std::map<std::string, std::string>& additionalData);
333
334 /**
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600335 * Unique name for the rail.
336 */
337 std::string name{};
338
339 /**
340 * D-Bus inventory path of a system component which must be present in order
341 * for the rail to be present.
342 *
343 * If not specified, the rail is assumed to always be present.
344 */
345 std::optional<std::string> presence{};
346
347 /**
348 * PMBus PAGE number of the rail.
349 */
350 std::optional<uint8_t> page{};
351
352 /**
Shawn McCarney16e493a2024-01-29 14:20:32 -0600353 * Specifies whether the rail is produced by a power supply.
354 */
355 bool isPsuRail{false};
356
357 /**
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600358 * Specifies whether to check the value of the PMBus STATUS_VOUT command
359 * when determining the pgood status of the rail.
360 *
361 * If one of the error bits is set in STATUS_VOUT, the rail pgood will be
362 * considered false.
363 */
364 bool checkStatusVout{false};
365
366 /**
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600367 * Specifies whether to compare the output voltage to the undervoltage fault
368 * limit when determining the pgood status of the rail.
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600369 *
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600370 * If the output voltage is below this limit, the rail pgood will be
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600371 * considered false.
372 *
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600373 * Uses the values of the PMBus READ_VOUT and VOUT_UV_FAULT_LIMIT commands.
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600374 */
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600375 bool compareVoltageToLimit{false};
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600376
377 /**
378 * GPIO to read to determine the pgood status of the rail.
379 */
380 std::optional<GPIO> gpio{};
381};
382
383} // namespace phosphor::power::sequencer