blob: 040eb812a6543697fd7dbf3268997618131cb193 [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) :
Patrick Williamsf5402192024-08-16 15:20:53 -040097 name{name}, presence{presence}, page{page},
98 isPsuRail{isPowerSupplyRail}, checkStatusVout{checkStatusVout},
Shawn McCarney9ec0d432024-02-09 18:26:00 -060099 compareVoltageToLimit{compareVoltageToLimit}, gpio{gpio}
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600100 {
101 // If checking STATUS_VOUT or output voltage, verify PAGE was specified
Shawn McCarney24956592024-02-19 18:58:57 -0600102 if ((checkStatusVout || compareVoltageToLimit) && !page)
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600103 {
104 throw std::invalid_argument{"PMBus PAGE is required"};
105 }
106 }
107
108 /**
109 * Returns the unique name for the rail.
110 *
111 * @return rail name
112 */
113 const std::string& getName() const
114 {
115 return name;
116 }
117
118 /**
119 * Returns the D-Bus inventory path of a system component which must be
120 * present in order for the rail to be present.
121 *
122 * @return inventory path for presence detection
123 */
124 const std::optional<std::string>& getPresence() const
125 {
126 return presence;
127 }
128
129 /**
130 * Returns the PMBus PAGE number of the rail.
131 *
132 * @return PAGE number for rail
133 */
134 const std::optional<uint8_t>& getPage() const
135 {
136 return page;
137 }
138
139 /**
Shawn McCarney16e493a2024-01-29 14:20:32 -0600140 * Returns whether the rail is produced by a power supply.
141 *
142 * @return true if rail is produced by a power supply, false otherwise
143 */
144 bool isPowerSupplyRail() const
145 {
146 return isPsuRail;
147 }
148
149 /**
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600150 * Returns whether the value of the PMBus STATUS_VOUT command is checked
151 * when determining the pgood status of the rail.
152 *
153 * @return true if STATUS_VOUT is checked, false otherwise
154 */
155 bool getCheckStatusVout() const
156 {
157 return checkStatusVout;
158 }
159
160 /**
161 * Returns whether the output voltage should be compared to the undervoltage
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600162 * fault limit when determining the pgood status of the rail.
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600163 *
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600164 * @return true if output voltage is compared to limit, false otherwise
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600165 */
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600166 bool getCompareVoltageToLimit() const
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600167 {
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600168 return compareVoltageToLimit;
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600169 }
170
171 /**
172 * Returns the GPIO to read to determine the pgood status of the rail.
173 *
174 * @return GPIO
175 */
176 const std::optional<GPIO>& getGPIO() const
177 {
178 return gpio;
179 }
180
Shawn McCarney24956592024-02-19 18:58:57 -0600181 /**
182 * Returns whether the rail is present.
183 *
184 * Returns true if no inventory path was specified for presence detection.
185 *
186 * @param services System services like hardware presence and the journal
187 * @return true if rail is present, false otherwise
188 */
189 bool isPresent(Services& services);
190
191 /**
192 * Returns the value of the PMBus STATUS_WORD command for the rail.
193 *
194 * Reads the value from the specified device. The returned value is in
195 * host-endian order.
196 *
197 * Throws an exception if the value could not be obtained.
198 *
199 * @param device Power sequencer device that enables and monitors the rail
200 * @return STATUS_WORD value
201 */
202 uint16_t getStatusWord(PowerSequencerDevice& device);
203
204 /**
205 * Returns the value of the PMBus STATUS_VOUT command for the rail.
206 *
207 * Reads the value from the specified device.
208 *
209 * Throws an exception if the value could not be obtained.
210 *
211 * @param device Power sequencer device that enables and monitors the rail
212 * @return STATUS_VOUT value
213 */
214 uint8_t getStatusVout(PowerSequencerDevice& device);
215
216 /**
217 * Returns the value of the PMBus READ_VOUT command for the rail.
218 *
219 * Reads the value from the specified device. The returned value is in
220 * volts.
221 *
222 * Throws an exception if the value could not be obtained.
223 *
224 * @param device Power sequencer device that enables and monitors the rail
225 * @return READ_VOUT value in volts
226 */
227 double getReadVout(PowerSequencerDevice& device);
228
229 /**
230 * Returns the value of the PMBus VOUT_UV_FAULT_LIMIT command for the rail.
231 *
232 * Reads the value from the specified device. The returned value is in
233 * volts.
234 *
235 * Throws an exception if the value could not be obtained.
236 *
237 * @param device Power sequencer device that enables and monitors the rail
238 * @return VOUT_UV_FAULT_LIMIT value in volts
239 */
240 double getVoutUVFaultLimit(PowerSequencerDevice& device);
241
242 /**
243 * Returns whether a pgood (power good) fault has occurred on the rail.
244 *
245 * Throws an exception if an error occurs while trying to obtain the rail
246 * status.
247 *
248 * @param device Power sequencer device that enables and monitors the rail
249 * @param services System services like hardware presence and the journal
250 * @param gpioValues GPIO values obtained from the device (if any)
251 * @param additionalData Additional data to include in an error log if this
252 * method returns true
253 * @return true if a pgood fault was found on the rail, false otherwise
254 */
255 bool hasPgoodFault(PowerSequencerDevice& device, Services& services,
256 const std::vector<int>& gpioValues,
257 std::map<std::string, std::string>& additionalData);
258
Shawn McCarney24956592024-02-19 18:58:57 -0600259 /**
260 * Returns whether the PMBus STATUS_VOUT command indicates a pgood fault
261 * has occurred on the rail.
262 *
263 * Throws an exception if an error occurs while trying to obtain the rail
264 * status.
265 *
266 * @param device Power sequencer device that enables and monitors the rail
267 * @param services System services like hardware presence and the journal
268 * @param additionalData Additional data to include in an error log if this
269 * method returns true
270 * @return true if a pgood fault was found on the rail, false otherwise
271 */
272 bool hasPgoodFaultStatusVout(
273 PowerSequencerDevice& device, Services& services,
274 std::map<std::string, std::string>& additionalData);
275
276 /**
277 * Returns whether a GPIO value indicates a pgood fault has occurred on the
278 * rail.
279 *
280 * Throws an exception if an error occurs while trying to obtain the rail
281 * status.
282 *
283 * @param device Power sequencer device that enables and monitors the rail
Shawn McCarney16275832024-06-27 10:14:11 -0500284 * @param services System services like hardware presence and the journal
Shawn McCarney24956592024-02-19 18:58:57 -0600285 * @param gpioValues GPIO values obtained from the device (if any)
286 * @param additionalData Additional data to include in an error log if this
287 * method returns true
288 * @return true if a pgood fault was found on the rail, false otherwise
289 */
Shawn McCarney16275832024-06-27 10:14:11 -0500290 bool hasPgoodFaultGPIO(PowerSequencerDevice& device, Services& services,
Shawn McCarney24956592024-02-19 18:58:57 -0600291 const std::vector<int>& gpioValues,
292 std::map<std::string, std::string>& additionalData);
293
294 /**
295 * Returns whether the output voltage is below the undervoltage limit
296 * indicating a pgood fault has occurred on the rail.
297 *
298 * Throws an exception if an error occurs while trying to obtain the rail
299 * status.
300 *
301 * @param device Power sequencer device that enables and monitors the rail
302 * @param services System services like hardware presence and the journal
303 * @param additionalData Additional data to include in an error log if this
304 * method returns true
305 * @return true if a pgood fault was found on the rail, false otherwise
306 */
307 bool hasPgoodFaultOutputVoltage(
308 PowerSequencerDevice& device, Services& services,
309 std::map<std::string, std::string>& additionalData);
310
Shawn McCarney16275832024-06-27 10:14:11 -0500311 private:
312 /**
313 * Verifies that a PMBus PAGE number is defined for the rail.
314 *
315 * Throws an exception if a PAGE number is not defined.
316 */
317 void verifyHasPage();
318
Shawn McCarney24956592024-02-19 18:58:57 -0600319 /**
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