1*b602aad5SDaniel Hsu #pragma once 2*b602aad5SDaniel Hsu #include "common/include/i2c/i2c.hpp" 3*b602aad5SDaniel Hsu 4*b602aad5SDaniel Hsu #include <phosphor-logging/lg2.hpp> 5*b602aad5SDaniel Hsu 6*b602aad5SDaniel Hsu #include <chrono> 7*b602aad5SDaniel Hsu #include <iostream> 8*b602aad5SDaniel Hsu #include <string_view> 9*b602aad5SDaniel Hsu #include <unordered_map> 10*b602aad5SDaniel Hsu #include <utility> 11*b602aad5SDaniel Hsu 12*b602aad5SDaniel Hsu namespace phosphor::software::cpld 13*b602aad5SDaniel Hsu { 14*b602aad5SDaniel Hsu 15*b602aad5SDaniel Hsu enum class latticeChip 16*b602aad5SDaniel Hsu { 17*b602aad5SDaniel Hsu LCMXO2_4000HC, 18*b602aad5SDaniel Hsu LCMXO3LF_2100C, 19*b602aad5SDaniel Hsu LCMXO3LF_4300C, 20*b602aad5SDaniel Hsu LCMXO3D_4300, 21*b602aad5SDaniel Hsu LCMXO3D_9400, 22*b602aad5SDaniel Hsu UNSUPPORTED = -1, 23*b602aad5SDaniel Hsu }; 24*b602aad5SDaniel Hsu 25*b602aad5SDaniel Hsu enum class latticeStringType 26*b602aad5SDaniel Hsu { 27*b602aad5SDaniel Hsu typeString, 28*b602aad5SDaniel Hsu modelString, 29*b602aad5SDaniel Hsu }; 30*b602aad5SDaniel Hsu 31*b602aad5SDaniel Hsu inline std::string getLatticeChipStr(latticeChip chip, 32*b602aad5SDaniel Hsu latticeStringType stringType) 33*b602aad5SDaniel Hsu { 34*b602aad5SDaniel Hsu static const std::unordered_map<latticeChip, std::string> chipStringMap = { 35*b602aad5SDaniel Hsu {latticeChip::LCMXO2_4000HC, "LCMXO2_4000HC"}, 36*b602aad5SDaniel Hsu {latticeChip::LCMXO3LF_2100C, "LCMXO3LF_2100C"}, 37*b602aad5SDaniel Hsu {latticeChip::LCMXO3LF_4300C, "LCMXO3LF_4300C"}, 38*b602aad5SDaniel Hsu {latticeChip::LCMXO3D_4300, "LCMXO3D_4300"}, 39*b602aad5SDaniel Hsu {latticeChip::LCMXO3D_9400, "LCMXO3D_9400"}, 40*b602aad5SDaniel Hsu }; 41*b602aad5SDaniel Hsu auto chipString = chipStringMap.at(chip); 42*b602aad5SDaniel Hsu if (chipStringMap.find(chip) == chipStringMap.end()) 43*b602aad5SDaniel Hsu { 44*b602aad5SDaniel Hsu lg2::error("Unsupported chip enum: {CHIPENUM}", "CHIPENUM", chip); 45*b602aad5SDaniel Hsu return ""; 46*b602aad5SDaniel Hsu } 47*b602aad5SDaniel Hsu 48*b602aad5SDaniel Hsu switch (stringType) 49*b602aad5SDaniel Hsu { 50*b602aad5SDaniel Hsu case latticeStringType::typeString: 51*b602aad5SDaniel Hsu return std::string("Lattice" + chipString + "Firmware"); 52*b602aad5SDaniel Hsu case latticeStringType::modelString: 53*b602aad5SDaniel Hsu std::replace(chipString.begin(), chipString.end(), '_', '-'); 54*b602aad5SDaniel Hsu return chipString; 55*b602aad5SDaniel Hsu default: 56*b602aad5SDaniel Hsu lg2::error("Unsupported string type: {STRINGTYPE}", "STRINGTYPE", 57*b602aad5SDaniel Hsu stringType); 58*b602aad5SDaniel Hsu return ""; 59*b602aad5SDaniel Hsu } 60*b602aad5SDaniel Hsu }; 61*b602aad5SDaniel Hsu 62*b602aad5SDaniel Hsu enum class latticeChipFamily 63*b602aad5SDaniel Hsu { 64*b602aad5SDaniel Hsu XO2, 65*b602aad5SDaniel Hsu XO3, 66*b602aad5SDaniel Hsu }; 67*b602aad5SDaniel Hsu 68*b602aad5SDaniel Hsu struct cpldInfo 69*b602aad5SDaniel Hsu { 70*b602aad5SDaniel Hsu latticeChipFamily chipFamily; 71*b602aad5SDaniel Hsu std::vector<uint8_t> deviceId; 72*b602aad5SDaniel Hsu }; 73*b602aad5SDaniel Hsu 74*b602aad5SDaniel Hsu const std::map<latticeChip, cpldInfo> supportedDeviceMap = { 75*b602aad5SDaniel Hsu {latticeChip::LCMXO2_4000HC, 76*b602aad5SDaniel Hsu {latticeChipFamily::XO2, {0x01, 0x2b, 0xc0, 0x43}}}, 77*b602aad5SDaniel Hsu {latticeChip::LCMXO3LF_2100C, 78*b602aad5SDaniel Hsu {latticeChipFamily::XO3, {0x61, 0x2b, 0xb0, 0x43}}}, 79*b602aad5SDaniel Hsu {latticeChip::LCMXO3LF_4300C, 80*b602aad5SDaniel Hsu {latticeChipFamily::XO3, {0x61, 0x2b, 0xc0, 0x43}}}, 81*b602aad5SDaniel Hsu {latticeChip::LCMXO3D_4300, 82*b602aad5SDaniel Hsu {latticeChipFamily::XO3, {0x01, 0x2e, 0x20, 0x43}}}, 83*b602aad5SDaniel Hsu {latticeChip::LCMXO3D_9400, 84*b602aad5SDaniel Hsu {latticeChipFamily::XO3, {0x21, 0x2e, 0x30, 0x43}}}, 85*b602aad5SDaniel Hsu }; 86*b602aad5SDaniel Hsu 87*b602aad5SDaniel Hsu struct cpldI2cInfo 88*b602aad5SDaniel Hsu { 89*b602aad5SDaniel Hsu unsigned long int fuseQuantity; 90*b602aad5SDaniel Hsu unsigned int* userFlashMemory; 91*b602aad5SDaniel Hsu unsigned int version; 92*b602aad5SDaniel Hsu unsigned int checksum; 93*b602aad5SDaniel Hsu std::vector<uint8_t> cfgData; 94*b602aad5SDaniel Hsu std::vector<uint8_t> ufmData; 95*b602aad5SDaniel Hsu }; 96*b602aad5SDaniel Hsu 97*b602aad5SDaniel Hsu enum cpldI2cCmd 98*b602aad5SDaniel Hsu { 99*b602aad5SDaniel Hsu commandEraseFlash = 0x0E, 100*b602aad5SDaniel Hsu commandDisableConfigInterface = 0x26, 101*b602aad5SDaniel Hsu commandReadStatusReg = 0x3C, 102*b602aad5SDaniel Hsu commandResetConfigFlash = 0x46, 103*b602aad5SDaniel Hsu commandProgramDone = 0x5E, 104*b602aad5SDaniel Hsu commandProgramPage = 0x70, 105*b602aad5SDaniel Hsu commandReadPage = 0x73, 106*b602aad5SDaniel Hsu commandEnableConfigMode = 0x74, 107*b602aad5SDaniel Hsu commandSetPageAddress = 0xB4, 108*b602aad5SDaniel Hsu commandReadFwVersion = 0xC0, 109*b602aad5SDaniel Hsu commandProgramUserCode = 0xC2, 110*b602aad5SDaniel Hsu commandReadDeviceId = 0xE0, 111*b602aad5SDaniel Hsu commandReadBusyFlag = 0xF0, 112*b602aad5SDaniel Hsu }; 113*b602aad5SDaniel Hsu 114*b602aad5SDaniel Hsu constexpr std::chrono::milliseconds waitBusyTime(200); 115*b602aad5SDaniel Hsu 116*b602aad5SDaniel Hsu class LatticeBaseCPLD 117*b602aad5SDaniel Hsu { 118*b602aad5SDaniel Hsu public: 119*b602aad5SDaniel Hsu LatticeBaseCPLD(sdbusplus::async::context& ctx, const uint16_t bus, 120*b602aad5SDaniel Hsu const uint8_t address, const std::string& chip, 121*b602aad5SDaniel Hsu const std::string& target, const bool debugMode) : 122*b602aad5SDaniel Hsu ctx(ctx), chip(chip), target(target), debugMode(debugMode), 123*b602aad5SDaniel Hsu i2cInterface(phosphor::i2c::I2C(bus, address)) 124*b602aad5SDaniel Hsu {} 125*b602aad5SDaniel Hsu virtual ~LatticeBaseCPLD() = default; 126*b602aad5SDaniel Hsu LatticeBaseCPLD(const LatticeBaseCPLD&) = delete; 127*b602aad5SDaniel Hsu LatticeBaseCPLD& operator=(const LatticeBaseCPLD&) = delete; 128*b602aad5SDaniel Hsu LatticeBaseCPLD(LatticeBaseCPLD&&) noexcept = delete; 129*b602aad5SDaniel Hsu LatticeBaseCPLD& operator=(LatticeBaseCPLD&&) noexcept = delete; 130*b602aad5SDaniel Hsu 131*b602aad5SDaniel Hsu sdbusplus::async::task<bool> updateFirmware( 132*b602aad5SDaniel Hsu const uint8_t* image, size_t imageSize, 133*b602aad5SDaniel Hsu std::function<bool(int)> progressCallBack); 134*b602aad5SDaniel Hsu 135*b602aad5SDaniel Hsu sdbusplus::async::task<bool> getVersion(std::string& version); 136*b602aad5SDaniel Hsu 137*b602aad5SDaniel Hsu protected: 138*b602aad5SDaniel Hsu sdbusplus::async::context& ctx; 139*b602aad5SDaniel Hsu cpldI2cInfo fwInfo{}; 140*b602aad5SDaniel Hsu std::string chip; 141*b602aad5SDaniel Hsu std::string target; 142*b602aad5SDaniel Hsu std::vector<uint8_t> sumOnly; 143*b602aad5SDaniel Hsu bool isLCMXO3D = false; 144*b602aad5SDaniel Hsu bool debugMode = false; 145*b602aad5SDaniel Hsu phosphor::i2c::I2C i2cInterface; 146*b602aad5SDaniel Hsu 147*b602aad5SDaniel Hsu virtual sdbusplus::async::task<bool> prepareUpdate(const uint8_t*, 148*b602aad5SDaniel Hsu size_t) = 0; 149*b602aad5SDaniel Hsu virtual sdbusplus::async::task<bool> doUpdate() = 0; 150*b602aad5SDaniel Hsu virtual sdbusplus::async::task<bool> finishUpdate() = 0; 151*b602aad5SDaniel Hsu 152*b602aad5SDaniel Hsu bool jedFileParser(const uint8_t* image, size_t imageSize); 153*b602aad5SDaniel Hsu bool verifyChecksum(); 154*b602aad5SDaniel Hsu sdbusplus::async::task<bool> enableProgramMode(); 155*b602aad5SDaniel Hsu sdbusplus::async::task<bool> resetConfigFlash(); 156*b602aad5SDaniel Hsu sdbusplus::async::task<bool> programDone(); 157*b602aad5SDaniel Hsu sdbusplus::async::task<bool> disableConfigInterface(); 158*b602aad5SDaniel Hsu sdbusplus::async::task<bool> waitBusyAndVerify(); 159*b602aad5SDaniel Hsu 160*b602aad5SDaniel Hsu private: 161*b602aad5SDaniel Hsu virtual sdbusplus::async::task<bool> readUserCode(uint32_t&) = 0; 162*b602aad5SDaniel Hsu sdbusplus::async::task<bool> readBusyFlag(uint8_t& busyFlag); 163*b602aad5SDaniel Hsu sdbusplus::async::task<bool> readStatusReg(uint8_t& statusReg); 164*b602aad5SDaniel Hsu static std::string uint32ToHexStr(uint32_t value); 165*b602aad5SDaniel Hsu }; 166*b602aad5SDaniel Hsu 167*b602aad5SDaniel Hsu } // namespace phosphor::software::cpld 168