1 #pragma once
2 
3 #include <algorithm>
4 #include <experimental/filesystem>
5 #include <map>
6 #include <vector>
7 #include "device.hpp"
8 #include "gpio.hpp"
9 #include "pmbus.hpp"
10 #include "types.hpp"
11 
12 namespace witherspoon
13 {
14 namespace power
15 {
16 
17 /**
18  * @class UCD90160
19  *
20  * This class implements fault analysis for the UCD90160
21  * power sequencer device.
22  *
23  */
24 class UCD90160 : public Device
25 {
26     public:
27 
28         UCD90160() = delete;
29         ~UCD90160() = default;
30         UCD90160(const UCD90160&) = delete;
31         UCD90160& operator=(const UCD90160&) = delete;
32         UCD90160(UCD90160&&) = default;
33         UCD90160& operator=(UCD90160&&) = default;
34 
35         /**
36          * Constructor
37          *
38          * @param[in] instance - the device instance number
39          */
40         UCD90160(size_t instance);
41 
42         /**
43          * Analyzes the device for errors when the device is
44          * known to be in an error state.  A log will be created.
45          */
46         void onFailure() override;
47 
48         /**
49          * Checks the device for errors and only creates a log
50          * if one is found.
51          */
52         void analyze() override;
53 
54         /**
55          * Clears faults in the device
56          */
57         void clearFaults() override
58         {
59         }
60 
61     private:
62 
63         /**
64          * Reports an error for a GPU PGOOD failure
65          *
66          * @param[in] callout - the GPU callout string
67          */
68         void gpuPGOODError(const std::string& callout);
69 
70         /**
71          * Reports an error for a GPU OverTemp failure
72          *
73          * @param[in] callout - the GPU callout string
74          */
75         void gpuOverTempError(const std::string& callout);
76 
77         /**
78          * Given the device path for a chip, find its gpiochip
79          * path
80          *
81          * @param[in] path - device path, like
82          *                   /sys/devices/.../i2c-11/11-0064
83          *
84          * @return fs::path - The gpiochip path, like
85          *                   /dev/gpiochip1
86          */
87         static std::experimental::filesystem::path findGPIODevice(
88                 const std::experimental::filesystem::path& path);
89 
90         /**
91          * Checks for VOUT faults on the device.
92          *
93          * This device can monitor voltages of its dependent
94          * devices, and VOUT faults are voltage faults
95          * on these devices.
96          *
97          * @return bool - true if an error log was created
98          */
99         bool checkVOUTFaults();
100 
101         /**
102          * Checks for PGOOD faults on the device.
103          *
104          * This device can monitor the PGOOD signals of its dependent
105          * devices, and this check will look for faults of
106          * those PGOODs.
107          *
108          * @param[in] polling - If this is running while polling for errors,
109          *                      as opposing to analyzing a fail condition.
110          *
111          * @return bool - true if an error log was created
112          */
113          bool checkPGOODFaults(bool polling);
114 
115         /**
116          * Creates an error log when the device has an error
117          * but it isn't a PGOOD or voltage failure.
118          */
119         void createPowerFaultLog();
120 
121         /**
122          * Reads the status_word register
123          *
124          * @return uint16_t - the register contents
125          */
126         uint16_t readStatusWord();
127 
128         /**
129          * Reads the mfr_status register
130          *
131          * @return uint32_t - the register contents
132          */
133         uint32_t readMFRStatus();
134 
135         /**
136          * Says if we've already logged a Vout fault
137          *
138          * The policy is only 1 of the same error will
139          * be logged for the duration of a class instance.
140          *
141          * @param[in] page - the page to check
142          *
143          * @return bool - if we've already logged a fault against
144          *                this page
145          */
146         inline bool isVoutFaultLogged(uint32_t page) const
147         {
148             return std::find(voutErrors.begin(),
149                              voutErrors.end(),
150                              page) != voutErrors.end();
151         }
152 
153         /**
154          * Saves that a Vout fault has been logged
155          *
156          * @param[in] page - the page the error was logged against
157          */
158         inline void setVoutFaultLogged(uint32_t page)
159         {
160             voutErrors.push_back(page);
161         }
162 
163         /**
164          * Says if we've already logged a PGOOD fault
165          *
166          * The policy is only 1 of the same errors will
167          * be logged for the duration of a class instance.
168          *
169          * @param[in] input - the input to check
170          *
171          * @return bool - if we've already logged a fault against
172          *                this input
173          */
174         inline bool isPGOODFaultLogged(uint32_t input) const
175         {
176             return std::find(pgoodErrors.begin(),
177                              pgoodErrors.end(),
178                              input) != pgoodErrors.end();
179         }
180 
181         /**
182          * Saves that a PGOOD fault has been logged
183          *
184          * @param[in] input - the input the error was logged against
185          */
186         inline void setPGOODFaultLogged(uint32_t input)
187         {
188             pgoodErrors.push_back(input);
189         }
190 
191         /**
192          * List of pages that Vout errors have
193          * already been logged against
194          */
195         std::vector<uint32_t> voutErrors;
196 
197         /**
198          * List of inputs that PGOOD errors have
199          * already been logged against
200          */
201         std::vector<uint32_t> pgoodErrors;
202 
203         /**
204          * The read/write interface to this hardware
205          */
206         pmbus::PMBus interface;
207 
208         /**
209          * A map of GPI pin IDs to the GPIO object
210          * used to access them
211          */
212         std::map<size_t, std::unique_ptr<gpio::GPIO>> gpios;
213 
214         /**
215          * Keeps track of device access errors to avoid repeatedly
216          * logging errors for bad hardware
217          */
218         bool accessError = false;
219 
220         /**
221          * The path to the GPIO device used to read
222          * the GPI (PGOOD) status
223          */
224         std::experimental::filesystem::path gpioDevice;
225 
226         /**
227          * Map of device instance to the instance specific data
228          */
229         static const ucd90160::DeviceMap deviceMap;
230 };
231 
232 }
233 }
234