i2c-vr: add RAA22X Gen2 support
Extend ISL69269 to support Renesas Gen2 VR devices which share
similar programming interfaces but use slightly different registers.
Tested:
```
1. Check firmware info: (current version 5FFB1D09)
~$ curl -k -u root:0penBmc -X GET https://10.2.230.66/redfish/v1/UpdateService/FirmwareInventory/Catalina_PDB_vr_n1_8217
{
"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/Catalina_PDB_vr_n1_8217",
"@odata.type": "#SoftwareInventory.v1_1_0.SoftwareInventory",
"Description": "Unknown image",
"Id": "Catalina_PDB_vr_n1_8217",
"Name": "Software Inventory",
"Status": {
"Health": "OK",
"HealthRollup": "OK",
"State": "Enabled"
},
"Updateable": true,
"Version": "5FFB1D09"
}
2. Trigger Update: (update to version C001A89C)
~$ curl -k -u root:0penBmc \
-H "Content-Type:multipart/form-data" \
-X POST \
-F UpdateParameters="{\"Targets\":[\"/redfish/v1/UpdateService/FirmwareInventory/Catalina_PDB_vr_n1_8217\"],\"@Redfish.OperationApplyTime\":\"OnReset\"};type=application/json" \
-F "UpdateFile=@catalina-raa-n1_C001A89C.pldm;type=application/octet-stream" \
https://10.2.230.66/redfish/v1/UpdateService/update-multipart
{
"@odata.id": "/redfish/v1/TaskService/Tasks/0",
"@odata.type": "#Task.v1_4_3.Task",
"HidePayload": false,
"Id": "0",
"Messages": [
{
"@odata.type": "#Message.v1_1_1.Message",
"Message": "The task with Id '0' has started.",
"MessageArgs": [
"0"
],
"MessageId": "TaskEvent.1.0.TaskStarted",
"MessageSeverity": "OK",
"Resolution": "None."
}
],
"Name": "Task 0",
"Payload": {
"HttpHeaders": [],
"HttpOperation": "POST",
"TargetUri": "/redfish/v1/UpdateService/update-multipart"
},
"PercentComplete": 0,
"StartTime": "2025-09-17T17:15:50+00:00",
"TaskMonitor": "/redfish/v1/TaskService/TaskMonitors/0",
"TaskState": "Running",
"TaskStatus": "OK"
}
3. After AC cycle check firmware info again:
~$ curl -k -u root:0penBmc -X GET https://10.2.230.66/redfish/v1/UpdateService/FirmwareInventory/Catalina_PDB_vr_n1_332
{
"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/Catalina_PDB_vr_n1_332",
"@odata.type": "#SoftwareInventory.v1_1_0.SoftwareInventory",
"Description": "Unknown image",
"Id": "Catalina_PDB_vr_n1_332",
"Name": "Software Inventory",
"Status": {
"Health": "OK",
"HealthRollup": "OK",
"State": "Enabled"
},
"Updateable": true,
"Version": "C001A89C"
}
```
Change-Id: Idd8e3d147a0191b45f465508e13b4ac0bc94e92a
Signed-off-by: Cosmo Chou <cosmo.chou@quantatw.com>
diff --git a/i2c-vr/isl69269/isl69269.cpp b/i2c-vr/isl69269/isl69269.cpp
index 399a80f..81d1e93 100644
--- a/i2c-vr/isl69269/isl69269.cpp
+++ b/i2c-vr/isl69269/isl69269.cpp
@@ -26,6 +26,7 @@
constexpr uint8_t gen3Legacy = 1;
constexpr uint8_t gen3Production = 2;
+constexpr uint8_t gen2Hex = 3;
constexpr uint16_t cfgId = 7;
constexpr uint16_t gen3FileHead = 5;
@@ -50,9 +51,21 @@
constexpr uint8_t threeByteLen = 3;
constexpr uint8_t fourByteLen = 4;
+// RAA Gen2
+constexpr uint8_t gen2RegProgStatus = 0x07;
+constexpr uint8_t gen2RegCRC = 0x3F;
+constexpr uint8_t gen2RegRemainginWrites = 0xC2;
+
+constexpr uint32_t gen2RevMin = 0x02000003;
+
+constexpr uint8_t hexFileRev = 0x00;
+constexpr uint16_t gen2FileHead = 6;
+constexpr uint16_t gen2CRC = 600 - gen2FileHead;
+
ISL69269::ISL69269(sdbusplus::async::context& ctx, uint16_t bus,
- uint16_t address) :
- VoltageRegulator(ctx), i2cInterface(phosphor::i2c::I2C(bus, address))
+ uint16_t address, Gen gen) :
+ VoltageRegulator(ctx), i2cInterface(phosphor::i2c::I2C(bus, address)),
+ generation(gen)
{}
inline void shiftLeftFromLSB(const uint8_t* data, uint32_t* result)
@@ -140,7 +153,8 @@
uint8_t tbuf[defaultBufferSize] = {0};
uint8_t rbuf[defaultBufferSize] = {0};
- tbuf[0] = regRemainginWrites;
+ tbuf[0] =
+ (generation == Gen::Gen2) ? gen2RegRemainginWrites : regRemainginWrites;
tbuf[1] = 0x00;
if (!(co_await dmaReadWrite(tbuf, rbuf)))
{
@@ -154,6 +168,12 @@
sdbusplus::async::task<bool> ISL69269::getHexMode(uint8_t* mode)
{
+ if (generation == Gen::Gen2)
+ {
+ *mode = gen2Hex;
+ co_return true;
+ }
+
uint8_t tbuf[defaultBufferSize] = {0};
uint8_t rbuf[defaultBufferSize] = {0};
@@ -210,7 +230,9 @@
uint8_t rlen = deviceRevisionLen + 1;
tbuf[0] = pmBusDeviceRev;
+ // NOLINTBEGIN(clang-analyzer-core.uninitialized.Branch)
if (!(co_await i2cInterface.sendReceive(tbuf, tlen, rbuf, rlen)))
+ // NOLINTEND(clang-analyzer-core.uninitialized.Branch)
{
error("getDeviceRevision failed with sendreceive");
co_return false;
@@ -233,7 +255,7 @@
uint8_t tbuf[defaultBufferSize] = {0};
uint8_t rbuf[defaultBufferSize] = {0};
- tbuf[0] = regCRC;
+ tbuf[0] = (generation == Gen::Gen2) ? gen2RegCRC : regCRC;
if (!(co_await dmaReadWrite(tbuf, rbuf)))
{
error("getCRC failed");
@@ -282,19 +304,27 @@
debug("device revision from config: {ID}", "ID", lg2::hex,
configuration.devRevExp);
- // According to programing guide:
- // If legacy hex file
- // MSB device revision == 0x00 | 0x01
- if (configuration.devRevExp < (gen3SWRevMin << 24))
+ if (generation != Gen::Gen2)
{
- debug("Legacy hex file format recognized");
- configuration.mode = gen3Legacy;
+ // According to programing guide:
+ // If legacy hex file
+ // MSB device revision == 0x00 | 0x01
+ if (configuration.devRevExp < (gen3SWRevMin << 24))
+ {
+ debug("Legacy hex file format recognized");
+ configuration.mode = gen3Legacy;
+ }
+ else
+ {
+ debug("Production hex file format recognized");
+ configuration.mode = gen3Production;
+ }
}
- else
- {
- debug("Production hex file format recognized");
- configuration.mode = gen3Production;
- }
+ }
+ else if (sepLine[3] == hexFileRev)
+ {
+ debug("Gen2 hex file format recognized");
+ configuration.mode = gen2Hex;
}
}
else if (sepLine[0] == recordTypeData)
@@ -345,6 +375,15 @@
lg2::hex, configuration.crcExp);
}
break;
+ case gen2CRC:
+ if (configuration.mode == gen2Hex)
+ {
+ std::memcpy(&configuration.crcExp, &sepLine[4],
+ checksumLen);
+ debug("Config Gen2 CRC: {CRC}", "CRC", lg2::hex,
+ configuration.crcExp);
+ }
+ break;
}
dcnt++;
}
@@ -415,8 +454,16 @@
uint8_t rbuf[programBufferSize] = {0};
int retry = 3;
- tbuf[0] = regProgStatus;
- tbuf[1] = 0x00;
+ if (generation == Gen::Gen2)
+ {
+ tbuf[0] = gen2RegProgStatus;
+ tbuf[1] = gen2RegProgStatus;
+ }
+ else
+ {
+ tbuf[0] = regProgStatus;
+ tbuf[1] = 0x00;
+ }
do
{
@@ -430,7 +477,7 @@
if (rbuf[0] & 0x01)
{
- debug("Programming succesful");
+ debug("Programming successful");
break;
}
if (--retry == 0)
@@ -476,7 +523,8 @@
tbuf[0] = regRestoreCfg;
tbuf[1] = configuration.cfgId;
- debug("Restore configurtion ID: {ID}", "ID", lg2::hex, configuration.cfgId);
+ debug("Restore configuration ID: {ID}", "ID", lg2::hex,
+ configuration.cfgId);
if (!(co_await dmaReadWrite(tbuf, rbuf)))
{
@@ -579,6 +627,16 @@
"revision requirements for production mode device not fulfilled");
}
break;
+ case gen2Hex:
+ if (devRev >= gen2RevMin)
+ {
+ debug("Gen2 mode revision checks out");
+ }
+ else
+ {
+ error("revision requirements for Gen2 device not fulfilled");
+ }
+ break;
}
if (!(co_await getCRC(&crc)))