1b54357f6SMatt Spinler #pragma once 2b54357f6SMatt Spinler 3f0f02b9aSMatt Spinler #include "device.hpp" 4f0f02b9aSMatt Spinler #include "gpio.hpp" 5f0f02b9aSMatt Spinler #include "pmbus.hpp" 6f0f02b9aSMatt Spinler #include "types.hpp" 7f0f02b9aSMatt Spinler 82c4fbc4cSPatrick Williams #include <sdbusplus/bus.hpp> 92c4fbc4cSPatrick Williams 10b54357f6SMatt Spinler #include <algorithm> 119c7897ceSBrandon Wyman #include <filesystem> 12b54357f6SMatt Spinler #include <map> 13b54357f6SMatt Spinler #include <vector> 14b54357f6SMatt Spinler 15b54357f6SMatt Spinler namespace witherspoon 16b54357f6SMatt Spinler { 17b54357f6SMatt Spinler namespace power 18b54357f6SMatt Spinler { 19b54357f6SMatt Spinler 208bc1283fSMatt Spinler // Error type, callout 21f0f02b9aSMatt Spinler using PartCallout = std::tuple<ucd90160::extraAnalysisType, std::string>; 228bc1283fSMatt Spinler 23b54357f6SMatt Spinler /** 24b54357f6SMatt Spinler * @class UCD90160 25b54357f6SMatt Spinler * 26b54357f6SMatt Spinler * This class implements fault analysis for the UCD90160 27b54357f6SMatt Spinler * power sequencer device. 28b54357f6SMatt Spinler * 29b54357f6SMatt Spinler */ 30b54357f6SMatt Spinler class UCD90160 : public Device 31b54357f6SMatt Spinler { 32b54357f6SMatt Spinler public: 33b54357f6SMatt Spinler UCD90160() = delete; 34b54357f6SMatt Spinler ~UCD90160() = default; 35b54357f6SMatt Spinler UCD90160(const UCD90160&) = delete; 36b54357f6SMatt Spinler UCD90160& operator=(const UCD90160&) = delete; 37b54357f6SMatt Spinler UCD90160(UCD90160&&) = default; 38b54357f6SMatt Spinler UCD90160& operator=(UCD90160&&) = default; 39b54357f6SMatt Spinler 40b54357f6SMatt Spinler /** 41b54357f6SMatt Spinler * Constructor 42b54357f6SMatt Spinler * 43b54357f6SMatt Spinler * @param[in] instance - the device instance number 44a8269652SMatt Spinler * @param[in] bus - D-Bus bus object 45b54357f6SMatt Spinler */ 461426a10bSPatrick Williams UCD90160(size_t instance, sdbusplus::bus_t& bus); 47b54357f6SMatt Spinler 48b54357f6SMatt Spinler /** 49b54357f6SMatt Spinler * Analyzes the device for errors when the device is 50b54357f6SMatt Spinler * known to be in an error state. A log will be created. 51b54357f6SMatt Spinler */ 52b54357f6SMatt Spinler void onFailure() override; 53b54357f6SMatt Spinler 54b54357f6SMatt Spinler /** 55b54357f6SMatt Spinler * Checks the device for errors and only creates a log 56b54357f6SMatt Spinler * if one is found. 57b54357f6SMatt Spinler */ 58b54357f6SMatt Spinler void analyze() override; 59b54357f6SMatt Spinler 60b54357f6SMatt Spinler /** 61b54357f6SMatt Spinler * Clears faults in the device 62b54357f6SMatt Spinler */ clearFaults()63b7ed5773SPatrick Williams void clearFaults() override {} 64b54357f6SMatt Spinler 65b54357f6SMatt Spinler private: 66b54357f6SMatt Spinler /** 677b14db24SMatt Spinler * Reports an error for a GPU PGOOD failure 687b14db24SMatt Spinler * 697b14db24SMatt Spinler * @param[in] callout - the GPU callout string 707b14db24SMatt Spinler */ 717b14db24SMatt Spinler void gpuPGOODError(const std::string& callout); 727b14db24SMatt Spinler 737b14db24SMatt Spinler /** 747b14db24SMatt Spinler * Reports an error for a GPU OverTemp failure 757b14db24SMatt Spinler * 767b14db24SMatt Spinler * @param[in] callout - the GPU callout string 777b14db24SMatt Spinler */ 787b14db24SMatt Spinler void gpuOverTempError(const std::string& callout); 797b14db24SMatt Spinler 807b14db24SMatt Spinler /** 8103c19db6SBrandon Wyman * Reports an error for a MEM_GOODx failure. 8203c19db6SBrandon Wyman * 8303c19db6SBrandon Wyman * @param[in] callout - The MEM callout string 8403c19db6SBrandon Wyman */ 8503c19db6SBrandon Wyman void memGoodError(const std::string& callout); 8603c19db6SBrandon Wyman 8703c19db6SBrandon Wyman /** 88fcd4a719SMatt Spinler * Given the device path for a chip, find its gpiochip 89fcd4a719SMatt Spinler * path 90fcd4a719SMatt Spinler * 91fcd4a719SMatt Spinler * @param[in] path - device path, like 92fcd4a719SMatt Spinler * /sys/devices/.../i2c-11/11-0064 93fcd4a719SMatt Spinler * 94fcd4a719SMatt Spinler * @return fs::path - The gpiochip path, like 95fcd4a719SMatt Spinler * /dev/gpiochip1 96110b2841SMatt Spinler */ 97*0ea214f2SPatrick Williams static std::filesystem::path findGPIODevice( 98*0ea214f2SPatrick Williams const std::filesystem::path& path); 99110b2841SMatt Spinler 100110b2841SMatt Spinler /** 101b54357f6SMatt Spinler * Checks for VOUT faults on the device. 102b54357f6SMatt Spinler * 103b54357f6SMatt Spinler * This device can monitor voltages of its dependent 104b54357f6SMatt Spinler * devices, and VOUT faults are voltage faults 105b54357f6SMatt Spinler * on these devices. 106b54357f6SMatt Spinler * 107b54357f6SMatt Spinler * @return bool - true if an error log was created 108b54357f6SMatt Spinler */ 109b54357f6SMatt Spinler bool checkVOUTFaults(); 110b54357f6SMatt Spinler 111b54357f6SMatt Spinler /** 112b54357f6SMatt Spinler * Checks for PGOOD faults on the device. 113b54357f6SMatt Spinler * 114b54357f6SMatt Spinler * This device can monitor the PGOOD signals of its dependent 115b54357f6SMatt Spinler * devices, and this check will look for faults of 116b54357f6SMatt Spinler * those PGOODs. 117b54357f6SMatt Spinler * 118b54357f6SMatt Spinler * @param[in] polling - If this is running while polling for errors, 119b54357f6SMatt Spinler * as opposing to analyzing a fail condition. 120b54357f6SMatt Spinler * 121b54357f6SMatt Spinler * @return bool - true if an error log was created 122b54357f6SMatt Spinler */ 123b54357f6SMatt Spinler bool checkPGOODFaults(bool polling); 124b54357f6SMatt Spinler 125b54357f6SMatt Spinler /** 126b54357f6SMatt Spinler * Creates an error log when the device has an error 127b54357f6SMatt Spinler * but it isn't a PGOOD or voltage failure. 128b54357f6SMatt Spinler */ 129b54357f6SMatt Spinler void createPowerFaultLog(); 130b54357f6SMatt Spinler 131b54357f6SMatt Spinler /** 132e7e432b4SMatt Spinler * Reads the status_word register 133e7e432b4SMatt Spinler * 134e7e432b4SMatt Spinler * @return uint16_t - the register contents 135e7e432b4SMatt Spinler */ 136e7e432b4SMatt Spinler uint16_t readStatusWord(); 137e7e432b4SMatt Spinler 138e7e432b4SMatt Spinler /** 139e7e432b4SMatt Spinler * Reads the mfr_status register 140e7e432b4SMatt Spinler * 141e7e432b4SMatt Spinler * @return uint32_t - the register contents 142e7e432b4SMatt Spinler */ 143e7e432b4SMatt Spinler uint32_t readMFRStatus(); 144e7e432b4SMatt Spinler 145e7e432b4SMatt Spinler /** 1468bc1283fSMatt Spinler * Does any additional fault analysis based on the 1478bc1283fSMatt Spinler * value of the extraAnalysisType field in the GPIOConfig 1488bc1283fSMatt Spinler * entry. 1498bc1283fSMatt Spinler * 1508bc1283fSMatt Spinler * Used to get better callouts. 1518bc1283fSMatt Spinler * 1528bc1283fSMatt Spinler * @param[in] config - the GPIOConfig entry to use 1538bc1283fSMatt Spinler * 1548bc1283fSMatt Spinler * @return bool - true if a HW error was found, false else 1558bc1283fSMatt Spinler */ 1568bc1283fSMatt Spinler bool doExtraAnalysis(const ucd90160::GPIConfig& config); 1578bc1283fSMatt Spinler 1588bc1283fSMatt Spinler /** 1598bc1283fSMatt Spinler * Does additional fault analysis using GPIOs to 1608bc1283fSMatt Spinler * specifically identify the failing part. 1618bc1283fSMatt Spinler * 1628bc1283fSMatt Spinler * Used when there are too many PGOOD inputs for 1638bc1283fSMatt Spinler * the UCD90160 to handle, so just a summary bit 1648bc1283fSMatt Spinler * is wired into the chip, and then the specific 1658bc1283fSMatt Spinler * fault GPIOs are off of a different GPIO device, 1668bc1283fSMatt Spinler * like an IO expander. 1678bc1283fSMatt Spinler * 1688bc1283fSMatt Spinler * @param[in] type - the type of analysis to do 1698bc1283fSMatt Spinler * 1708bc1283fSMatt Spinler * @return bool - true if a HW error was found, false else 1718bc1283fSMatt Spinler */ 1728bc1283fSMatt Spinler bool doGPIOAnalysis(ucd90160::extraAnalysisType type); 1738bc1283fSMatt Spinler 1748bc1283fSMatt Spinler /** 175e7e432b4SMatt Spinler * Says if we've already logged a Vout fault 176e7e432b4SMatt Spinler * 177e7e432b4SMatt Spinler * The policy is only 1 of the same error will 178e7e432b4SMatt Spinler * be logged for the duration of a class instance. 179e7e432b4SMatt Spinler * 180e7e432b4SMatt Spinler * @param[in] page - the page to check 181e7e432b4SMatt Spinler * 182e7e432b4SMatt Spinler * @return bool - if we've already logged a fault against 183e7e432b4SMatt Spinler * this page 184e7e432b4SMatt Spinler */ isVoutFaultLogged(uint32_t page) const185e7e432b4SMatt Spinler inline bool isVoutFaultLogged(uint32_t page) const 186e7e432b4SMatt Spinler { 187f0f02b9aSMatt Spinler return std::find(voutErrors.begin(), voutErrors.end(), page) != 188f0f02b9aSMatt Spinler voutErrors.end(); 189e7e432b4SMatt Spinler } 190e7e432b4SMatt Spinler 191e7e432b4SMatt Spinler /** 192e7e432b4SMatt Spinler * Saves that a Vout fault has been logged 193e7e432b4SMatt Spinler * 194e7e432b4SMatt Spinler * @param[in] page - the page the error was logged against 195e7e432b4SMatt Spinler */ setVoutFaultLogged(uint32_t page)196e7e432b4SMatt Spinler inline void setVoutFaultLogged(uint32_t page) 197e7e432b4SMatt Spinler { 198e7e432b4SMatt Spinler voutErrors.push_back(page); 199e7e432b4SMatt Spinler } 200e7e432b4SMatt Spinler 201e7e432b4SMatt Spinler /** 202d998b736SMatt Spinler * Says if we've already logged a PGOOD fault 203d998b736SMatt Spinler * 204d998b736SMatt Spinler * The policy is only 1 of the same errors will 205d998b736SMatt Spinler * be logged for the duration of a class instance. 206d998b736SMatt Spinler * 207d998b736SMatt Spinler * @param[in] input - the input to check 208d998b736SMatt Spinler * 209d998b736SMatt Spinler * @return bool - if we've already logged a fault against 210d998b736SMatt Spinler * this input 211d998b736SMatt Spinler */ isPGOODFaultLogged(uint32_t input) const212d998b736SMatt Spinler inline bool isPGOODFaultLogged(uint32_t input) const 213d998b736SMatt Spinler { 214f0f02b9aSMatt Spinler return std::find(pgoodErrors.begin(), pgoodErrors.end(), input) != 215f0f02b9aSMatt Spinler pgoodErrors.end(); 216d998b736SMatt Spinler } 217d998b736SMatt Spinler 218d998b736SMatt Spinler /** 2198bc1283fSMatt Spinler * Says if we've already logged a specific fault 2208bc1283fSMatt Spinler * against a specific part 2218bc1283fSMatt Spinler * 2228bc1283fSMatt Spinler * @param[in] callout - error type and name tuple 2238bc1283fSMatt Spinler * 2248bc1283fSMatt Spinler * @return bool - if we've already logged this fault 2258bc1283fSMatt Spinler * against this part 2268bc1283fSMatt Spinler */ isPartCalledOut(const PartCallout & callout) const2278bc1283fSMatt Spinler inline bool isPartCalledOut(const PartCallout& callout) const 2288bc1283fSMatt Spinler { 229f0f02b9aSMatt Spinler return std::find(callouts.begin(), callouts.end(), callout) != 230f0f02b9aSMatt Spinler callouts.end(); 2318bc1283fSMatt Spinler } 2328bc1283fSMatt Spinler 2338bc1283fSMatt Spinler /** 234d998b736SMatt Spinler * Saves that a PGOOD fault has been logged 235d998b736SMatt Spinler * 236d998b736SMatt Spinler * @param[in] input - the input the error was logged against 237d998b736SMatt Spinler */ setPGOODFaultLogged(uint32_t input)238d998b736SMatt Spinler inline void setPGOODFaultLogged(uint32_t input) 239d998b736SMatt Spinler { 240d998b736SMatt Spinler pgoodErrors.push_back(input); 241d998b736SMatt Spinler } 242d998b736SMatt Spinler 243d998b736SMatt Spinler /** 2448bc1283fSMatt Spinler * Saves that a specific fault on a specific part has been done 2458bc1283fSMatt Spinler * 2468bc1283fSMatt Spinler * @param[in] callout - error type and name tuple 2478bc1283fSMatt Spinler */ setPartCallout(const PartCallout & callout)2488bc1283fSMatt Spinler inline void setPartCallout(const PartCallout& callout) 2498bc1283fSMatt Spinler { 2508bc1283fSMatt Spinler callouts.push_back(callout); 2518bc1283fSMatt Spinler } 2528bc1283fSMatt Spinler 2538bc1283fSMatt Spinler /** 254e7e432b4SMatt Spinler * List of pages that Vout errors have 255e7e432b4SMatt Spinler * already been logged against 256e7e432b4SMatt Spinler */ 257e7e432b4SMatt Spinler std::vector<uint32_t> voutErrors; 258e7e432b4SMatt Spinler 259e7e432b4SMatt Spinler /** 260d998b736SMatt Spinler * List of inputs that PGOOD errors have 261d998b736SMatt Spinler * already been logged against 262d998b736SMatt Spinler */ 263d998b736SMatt Spinler std::vector<uint32_t> pgoodErrors; 264d998b736SMatt Spinler 265d998b736SMatt Spinler /** 2668bc1283fSMatt Spinler * List of callouts that already been done 2678bc1283fSMatt Spinler */ 2688bc1283fSMatt Spinler std::vector<PartCallout> callouts; 2698bc1283fSMatt Spinler 2708bc1283fSMatt Spinler /** 271b54357f6SMatt Spinler * The read/write interface to this hardware 272b54357f6SMatt Spinler */ 273b54357f6SMatt Spinler pmbus::PMBus interface; 274b54357f6SMatt Spinler 275b54357f6SMatt Spinler /** 276d998b736SMatt Spinler * A map of GPI pin IDs to the GPIO object 277d998b736SMatt Spinler * used to access them 278d998b736SMatt Spinler */ 279d998b736SMatt Spinler std::map<size_t, std::unique_ptr<gpio::GPIO>> gpios; 280d998b736SMatt Spinler 281d998b736SMatt Spinler /** 282b54357f6SMatt Spinler * Keeps track of device access errors to avoid repeatedly 283b54357f6SMatt Spinler * logging errors for bad hardware 284b54357f6SMatt Spinler */ 285b54357f6SMatt Spinler bool accessError = false; 286b54357f6SMatt Spinler 287b54357f6SMatt Spinler /** 2888bc1283fSMatt Spinler * Keeps track of GPIO access errors when doing the in depth 2898bc1283fSMatt Spinler * PGOOD fault analysis to avoid repeatedly logging errors 2908bc1283fSMatt Spinler * for bad hardware 2918bc1283fSMatt Spinler */ 2928bc1283fSMatt Spinler bool gpioAccessError = false; 2938bc1283fSMatt Spinler 2948bc1283fSMatt Spinler /** 295110b2841SMatt Spinler * The path to the GPIO device used to read 296110b2841SMatt Spinler * the GPI (PGOOD) status 297110b2841SMatt Spinler */ 2989c7897ceSBrandon Wyman std::filesystem::path gpioDevice; 299110b2841SMatt Spinler 300110b2841SMatt Spinler /** 301a8269652SMatt Spinler * The D-Bus bus object 302a8269652SMatt Spinler */ 3031426a10bSPatrick Williams sdbusplus::bus_t& bus; 304a8269652SMatt Spinler 305a8269652SMatt Spinler /** 306b54357f6SMatt Spinler * Map of device instance to the instance specific data 307b54357f6SMatt Spinler */ 308b54357f6SMatt Spinler static const ucd90160::DeviceMap deviceMap; 309b54357f6SMatt Spinler }; 310b54357f6SMatt Spinler 311f0f02b9aSMatt Spinler } // namespace power 312f0f02b9aSMatt Spinler } // namespace witherspoon 313