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