blob: 5a49e1341687ce0fb988abd725fd6adbe063fa04 [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 "power_sequencer_device.hpp"
19#include "services.hpp"
20
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060021#include <cstdint>
Shawn McCarney24956592024-02-19 18:58:57 -060022#include <map>
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060023#include <optional>
24#include <stdexcept>
25#include <string>
Shawn McCarney24956592024-02-19 18:58:57 -060026#include <vector>
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060027
28namespace phosphor::power::sequencer
29{
30
31/**
32 * @struct GPIO
33 *
34 * General Purpose Input/Output (GPIO) that can be read to obtain the pgood
35 * status of a voltage rail.
36 */
37struct GPIO
38{
39 /**
40 * The libgpiod line offset of the GPIO.
41 */
42 unsigned int line{0};
43
44 /**
45 * Specifies whether the GPIO is active low.
46 *
47 * If true, the GPIO value 0 indicates a true pgood status. If false, the
48 * GPIO value 1 indicates a true pgood status.
49 */
50 bool activeLow{false};
51};
52
53/**
54 * @class Rail
55 *
56 * A voltage rail that is enabled or monitored by the power sequencer device.
57 */
58class Rail
59{
60 public:
61 // Specify which compiler-generated methods we want
62 Rail() = delete;
63 Rail(const Rail&) = delete;
64 Rail(Rail&&) = delete;
65 Rail& operator=(const Rail&) = delete;
66 Rail& operator=(Rail&&) = delete;
67 ~Rail() = default;
68
69 /**
70 * Constructor.
71 *
72 * Throws an exception if any of the input parameters are invalid.
73 *
74 * @param name Unique name for the rail
75 * @param presence Optional D-Bus inventory path of a system component which
76 * must be present in order for the rail to be present
77 * @param page Optional PMBus PAGE number of the rail. Required if
Shawn McCarney9ec0d432024-02-09 18:26:00 -060078 * checkStatusVout or compareVoltageToLimit is true.
Shawn McCarney16e493a2024-01-29 14:20:32 -060079 * @param isPowerSupplyRail Specifies whether the rail is produced by a
80 * power supply
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060081 * @param checkStatusVout Specifies whether to check the value of the PMBus
82 * STATUS_VOUT command when determining the pgood
83 * status of the rail
Shawn McCarney9ec0d432024-02-09 18:26:00 -060084 * @param compareVoltageToLimit Specifies whether to compare the output
85 * voltage to the undervoltage fault limit when
86 * determining the pgood status of the rail
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060087 * @param gpio Optional GPIO to read to determine the pgood status of the
88 * rail
89 */
90 explicit Rail(const std::string& name,
91 const std::optional<std::string>& presence,
Shawn McCarney16e493a2024-01-29 14:20:32 -060092 const std::optional<uint8_t>& page, bool isPowerSupplyRail,
Shawn McCarney9ec0d432024-02-09 18:26:00 -060093 bool checkStatusVout, bool compareVoltageToLimit,
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060094 const std::optional<GPIO>& gpio) :
95 name{name},
Shawn McCarney16e493a2024-01-29 14:20:32 -060096 presence{presence}, page{page}, isPsuRail{isPowerSupplyRail},
97 checkStatusVout{checkStatusVout},
Shawn McCarney9ec0d432024-02-09 18:26:00 -060098 compareVoltageToLimit{compareVoltageToLimit}, gpio{gpio}
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -060099 {
100 // If checking STATUS_VOUT or output voltage, verify PAGE was specified
Shawn McCarney24956592024-02-19 18:58:57 -0600101 if ((checkStatusVout || compareVoltageToLimit) && !page)
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600102 {
103 throw std::invalid_argument{"PMBus PAGE is required"};
104 }
105 }
106
107 /**
108 * Returns the unique name for the rail.
109 *
110 * @return rail name
111 */
112 const std::string& getName() const
113 {
114 return name;
115 }
116
117 /**
118 * Returns the D-Bus inventory path of a system component which must be
119 * present in order for the rail to be present.
120 *
121 * @return inventory path for presence detection
122 */
123 const std::optional<std::string>& getPresence() const
124 {
125 return presence;
126 }
127
128 /**
129 * Returns the PMBus PAGE number of the rail.
130 *
131 * @return PAGE number for rail
132 */
133 const std::optional<uint8_t>& getPage() const
134 {
135 return page;
136 }
137
138 /**
Shawn McCarney16e493a2024-01-29 14:20:32 -0600139 * Returns whether the rail is produced by a power supply.
140 *
141 * @return true if rail is produced by a power supply, false otherwise
142 */
143 bool isPowerSupplyRail() const
144 {
145 return isPsuRail;
146 }
147
148 /**
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600149 * Returns whether the value of the PMBus STATUS_VOUT command is checked
150 * when determining the pgood status of the rail.
151 *
152 * @return true if STATUS_VOUT is checked, false otherwise
153 */
154 bool getCheckStatusVout() const
155 {
156 return checkStatusVout;
157 }
158
159 /**
160 * Returns whether the output voltage should be compared to the undervoltage
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600161 * fault limit when determining the pgood status of the rail.
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600162 *
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600163 * @return true if output voltage is compared to limit, false otherwise
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600164 */
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600165 bool getCompareVoltageToLimit() const
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600166 {
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600167 return compareVoltageToLimit;
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600168 }
169
170 /**
171 * Returns the GPIO to read to determine the pgood status of the rail.
172 *
173 * @return GPIO
174 */
175 const std::optional<GPIO>& getGPIO() const
176 {
177 return gpio;
178 }
179
Shawn McCarney24956592024-02-19 18:58:57 -0600180 /**
181 * Returns whether the rail is present.
182 *
183 * Returns true if no inventory path was specified for presence detection.
184 *
185 * @param services System services like hardware presence and the journal
186 * @return true if rail is present, false otherwise
187 */
188 bool isPresent(Services& services);
189
190 /**
191 * Returns the value of the PMBus STATUS_WORD command for the rail.
192 *
193 * Reads the value from the specified device. The returned value is in
194 * host-endian order.
195 *
196 * Throws an exception if the value could not be obtained.
197 *
198 * @param device Power sequencer device that enables and monitors the rail
199 * @return STATUS_WORD value
200 */
201 uint16_t getStatusWord(PowerSequencerDevice& device);
202
203 /**
204 * Returns the value of the PMBus STATUS_VOUT command for the rail.
205 *
206 * Reads the value from the specified device.
207 *
208 * Throws an exception if the value could not be obtained.
209 *
210 * @param device Power sequencer device that enables and monitors the rail
211 * @return STATUS_VOUT value
212 */
213 uint8_t getStatusVout(PowerSequencerDevice& device);
214
215 /**
216 * Returns the value of the PMBus READ_VOUT command for the rail.
217 *
218 * Reads the value from the specified device. The returned value is in
219 * volts.
220 *
221 * Throws an exception if the value could not be obtained.
222 *
223 * @param device Power sequencer device that enables and monitors the rail
224 * @return READ_VOUT value in volts
225 */
226 double getReadVout(PowerSequencerDevice& device);
227
228 /**
229 * Returns the value of the PMBus VOUT_UV_FAULT_LIMIT command for the rail.
230 *
231 * Reads the value from the specified device. The returned value is in
232 * volts.
233 *
234 * Throws an exception if the value could not be obtained.
235 *
236 * @param device Power sequencer device that enables and monitors the rail
237 * @return VOUT_UV_FAULT_LIMIT value in volts
238 */
239 double getVoutUVFaultLimit(PowerSequencerDevice& device);
240
241 /**
242 * Returns whether a pgood (power good) fault has occurred on the rail.
243 *
244 * Throws an exception if an error occurs while trying to obtain the rail
245 * status.
246 *
247 * @param device Power sequencer device that enables and monitors the rail
248 * @param services System services like hardware presence and the journal
249 * @param gpioValues GPIO values obtained from the device (if any)
250 * @param additionalData Additional data to include in an error log if this
251 * method returns true
252 * @return true if a pgood fault was found on the rail, false otherwise
253 */
254 bool hasPgoodFault(PowerSequencerDevice& device, Services& services,
255 const std::vector<int>& gpioValues,
256 std::map<std::string, std::string>& additionalData);
257
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600258 private:
259 /**
Shawn McCarney24956592024-02-19 18:58:57 -0600260 * Verifies that a PMBus PAGE number is defined for the rail.
261 *
262 * Throws an exception if a PAGE number is not defined.
263 */
264 void verifyHasPage();
265
266 /**
267 * Returns whether the PMBus STATUS_VOUT command indicates a pgood fault
268 * has occurred on the rail.
269 *
270 * Throws an exception if an error occurs while trying to obtain the rail
271 * status.
272 *
273 * @param device Power sequencer device that enables and monitors the rail
274 * @param services System services like hardware presence and the journal
275 * @param additionalData Additional data to include in an error log if this
276 * method returns true
277 * @return true if a pgood fault was found on the rail, false otherwise
278 */
279 bool hasPgoodFaultStatusVout(
280 PowerSequencerDevice& device, Services& services,
281 std::map<std::string, std::string>& additionalData);
282
283 /**
284 * Returns whether a GPIO value indicates a pgood fault has occurred on the
285 * rail.
286 *
287 * Throws an exception if an error occurs while trying to obtain the rail
288 * status.
289 *
290 * @param device Power sequencer device that enables and monitors the rail
291 * @param gpioValues GPIO values obtained from the device (if any)
292 * @param additionalData Additional data to include in an error log if this
293 * method returns true
294 * @return true if a pgood fault was found on the rail, false otherwise
295 */
296 bool hasPgoodFaultGPIO(Services& services,
297 const std::vector<int>& gpioValues,
298 std::map<std::string, std::string>& additionalData);
299
300 /**
301 * Returns whether the output voltage is below the undervoltage limit
302 * indicating a pgood fault has occurred on the rail.
303 *
304 * Throws an exception if an error occurs while trying to obtain the rail
305 * status.
306 *
307 * @param device Power sequencer device that enables and monitors the rail
308 * @param services System services like hardware presence and the journal
309 * @param additionalData Additional data to include in an error log if this
310 * method returns true
311 * @return true if a pgood fault was found on the rail, false otherwise
312 */
313 bool hasPgoodFaultOutputVoltage(
314 PowerSequencerDevice& device, Services& services,
315 std::map<std::string, std::string>& additionalData);
316
317 /**
318 * Store pgood fault debug data in the specified additional data map.
319 *
320 * Stores data that is relevant regardless of which method was used to
321 * detect the pgood fault.
322 *
323 * @param device Power sequencer device that enables and monitors the rail
324 * @param services System services like hardware presence and the journal
325 * @param additionalData Additional data to include in an error log
326 */
327 void storePgoodFaultDebugData(
328 PowerSequencerDevice& device, Services& services,
329 std::map<std::string, std::string>& additionalData);
330
331 /**
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600332 * Unique name for the rail.
333 */
334 std::string name{};
335
336 /**
337 * D-Bus inventory path of a system component which must be present in order
338 * for the rail to be present.
339 *
340 * If not specified, the rail is assumed to always be present.
341 */
342 std::optional<std::string> presence{};
343
344 /**
345 * PMBus PAGE number of the rail.
346 */
347 std::optional<uint8_t> page{};
348
349 /**
Shawn McCarney16e493a2024-01-29 14:20:32 -0600350 * Specifies whether the rail is produced by a power supply.
351 */
352 bool isPsuRail{false};
353
354 /**
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600355 * Specifies whether to check the value of the PMBus STATUS_VOUT command
356 * when determining the pgood status of the rail.
357 *
358 * If one of the error bits is set in STATUS_VOUT, the rail pgood will be
359 * considered false.
360 */
361 bool checkStatusVout{false};
362
363 /**
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600364 * Specifies whether to compare the output voltage to the undervoltage fault
365 * limit when determining the pgood status of the rail.
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600366 *
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600367 * If the output voltage is below this limit, the rail pgood will be
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600368 * considered false.
369 *
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600370 * Uses the values of the PMBus READ_VOUT and VOUT_UV_FAULT_LIMIT commands.
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600371 */
Shawn McCarney9ec0d432024-02-09 18:26:00 -0600372 bool compareVoltageToLimit{false};
Shawn McCarneyd6e9bfe2024-01-05 17:52:04 -0600373
374 /**
375 * GPIO to read to determine the pgood status of the rail.
376 */
377 std::optional<GPIO> gpio{};
378};
379
380} // namespace phosphor::power::sequencer