Files
OpenBMC/0001-LUXSHARE_2026041701.patch
T

426 lines
13 KiB
Diff
Raw Normal View History

From 182a0516acfeffabf6f2ec863d078d3ef72b0265 Mon Sep 17 00:00:00 2001
From: Your Name <you@example.com>
Date: Thu, 23 Apr 2026 17:48:19 +0800
Subject: [PATCH] LUXSHARE_2026041701
---
.../dimm/dimm-spd-reader/dimmSpdReader.cpp | 281 ++++++++++++++----
1 file changed, 229 insertions(+), 52 deletions(-)
diff --git a/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReader.cpp b/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReader.cpp
index cd730713..7438cbd3 100755
--- a/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReader.cpp
+++ b/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReader.cpp
@@ -346,7 +346,7 @@ static int i3cWriteRead(std::string& i3cDev, uint8_t wBuf[], uint16_t wLen,
std::cout << "i3c data to write:" << std::endl;
for(int i=0; i<wLen; i++)
{
- std::cout << "wBuf[" << i << "]: " << (int)wBuf[i] << " ";
+ std::cout << "wBuf[" << i << "]: 0x" << std::hex << (int)wBuf[i] << std::dec << " ";
}
std::cout << std::endl;
}
@@ -391,8 +391,12 @@ static int i3cWriteRead(std::string& i3cDev, uint8_t wBuf[], uint16_t wLen,
if constexpr (debug)
{
- std::cout << "i3c received data:" << std::endl;
- std::cout << "rBuf[0]: " << (int)rBuf[0] << std::endl;
+ std::cout << "i3c received data:\n";
+ for (int i = 0; i < (int)rLen; i++)
+ {
+ std::cout << "rBuf[" << i << "]: 0x" << std::hex << (int)rBuf[i] << std::dec << " ";
+ }
+ std::cout << "\n";
}
close(fd);
@@ -452,7 +456,8 @@ int DIMMSpdReader::getPmicType(uint8_t cpuid, uint8_t rank)
uint8_t index[] = {0xc8, 0xcc, 0xd0};
uint16_t wLen = 2;
- uint8_t wrBuf[] = {0, 0};
+//Jim debug uint8_t wrBuf[] = {0, 0};
+ uint8_t wrBuf[] = {0, 0, 0}; //Jim debug
uint8_t rdBuf[] = {0};
uint16_t rLen = 1;
int spd = NUM_TO_SPD(rank);
@@ -494,6 +499,101 @@ int DIMMSpdReader::getPmicType(uint8_t cpuid, uint8_t rank)
gotType[cpuid][rank] = true;
+//Jim debug+S
+
+//----------------------------------------------------------------------------
+//A. 1B Write R30 = 0x84 // 1 byte format, set 2 byte mode
+//B. 2B Read R0030 //check 2 byte mode
+// if(R0030 == 0x84)
+// 2 byte mode + 1ms delay: R30 success
+// Else // Original 2 byte mode
+// C. 2B Write R0030 = 0x84
+// D. 2B Read R0030
+// if(R0030 == 0x84) //check 2 byte mode
+// 2 byte mode + 1ms delay: R30 success
+ if (pmicType[cpuid][rank] == PMIC5030)
+ {
+
+ int pmic = NUM_TO_PMIC(rank);
+ std::string i3cPmicName = I3C_ADDR(cpuid) + to_hex(pmic);
+
+ if constexpr (debug)
+ {
+ std::cout << "is PMIC5030"<< std::endl;
+ }
+ // 1. 1B Write R30 = 0x84
+ wLen = 2;
+ rLen = 0;
+ wrBuf[0] = 0x30; wrBuf[1] = 0x84;
+ rdBuf[0] = 0x00;
+ ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen);
+ if (ret < 0)
+ {
+ return -1;
+ }
+
+ if constexpr (debug)
+ {
+ std::cout << "first 1B Write R30 = 0x84" << std::endl;
+ }
+ std::this_thread::sleep_for(std::chrono::milliseconds(9));
+
+ // 2. 2B Read R0030
+ wLen = 2;
+ rLen = 1;
+ wrBuf[0] = 0x30; wrBuf[1] = 0x00;
+ rdBuf[0] = 0x00;
+ ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen);
+ if (ret < 0)
+ {
+ return -1;
+ }
+
+ if constexpr (debug)
+ {
+ std::cout << "2B Read R0030 = 0x" << std::hex << (int)rdBuf[0] << std::endl;
+ }
+
+
+ // Successful switch to 2 Byte mode
+ if(rdBuf[0] == 0x84)
+ {
+ if constexpr (debug)
+ {
+ std::cout << "Is 2 Byte mode" << std::endl;
+ }
+ }
+ // It was originally 2 bytes mode
+ else
+ {
+ //C2-2. 2B Write R30 = 0x84
+ wrBuf[0] = 0x30; wrBuf[1] = 0x00; wrBuf[2] = 0x84;
+ wLen = 3;
+ rLen = 0;
+ ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen);
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(9));
+ //C2-2. 2B Read R30 = 0x84
+ wrBuf[0] = 0x30; wrBuf[1] = 0x00;
+ wLen = 2;
+ rLen = 1;
+ ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen);
+ if constexpr (debug)
+ {
+ std::cout << "2B Read R0030 = " << std::hex << (int)rdBuf[0] << std::endl;
+ }
+
+ //Force the use of 1-byte mode
+ if(rdBuf[0] != 0x84)
+ {
+ twoByteMode[cpuid][rank] = false;
+ std::cout << "Force the use of 1-byte mode" << std::endl;
+ }
+
+ }
+ }
+
+//Jim debug+E
if constexpr (debug)
{
std::cout << "pmicType[" << (int)cpuid << "][" << (int)rank << "] = "<< (int)pmicType[cpuid][rank] << std::endl;
@@ -635,9 +735,11 @@ int DIMMSpdReader::getDIMMRegsVol(uint8_t cpuid, uint8_t rank, DimmData& dimmDat
int index = (pmicType[cpuid][rank] == PMIC5030) ? 6 : 4;
for(int i=0; i<index; i++) {
- rLen = 1;
+ //Write R30
+ rLen = 0; //Jim debug, For Renesas requirements, I3C write commands cannot be directly read; reading requires a separate I3C command.
if(twoByteMode[cpuid][rank])
{
+ adcValue = 0x4; //Jim debug, PMIC5030 fixed the 2 byte mode + 1ms
wrBuf[2] = adcValue | adcSel[i];
wLen = 3;
}
@@ -652,8 +754,14 @@ int DIMMSpdReader::getDIMMRegsVol(uint8_t cpuid, uint8_t rank, DimmData& dimmDat
{
return -1;
}
-
- std::this_thread::sleep_for(std::chrono::milliseconds(adcDelay[cpuid][rank]));
+//Jim debug std::this_thread::sleep_for(std::chrono::milliseconds(adcDelay[cpuid][rank]));
+//Jim debug+S
+ // For Renesas requirements, the JESD spec PMIC5030 needs a 9ms delay.
+ if(pmicType[cpuid][rank] == PMIC5030)
+ std::this_thread::sleep_for(std::chrono::milliseconds(9));
+ else
+ std::this_thread::sleep_for(std::chrono::milliseconds(adcDelay[cpuid][rank]));
+//Jim debug+E
wLen = twoByteMode[cpuid][rank] ? 2 : 1;
rLen = 1;
@@ -700,6 +808,7 @@ static double calStep31CurPower(int index, const uint8_t (&temp)[8])
return result;
}
+
int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& dimmData)
{
int ret = -1;
@@ -719,7 +828,8 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d
uint8_t adcSelect[] = {0x1b, 0, 0};
uint16_t curOut[8];
uint8_t temp[8];
- uint8_t rdBuf[] = {0};
+ uint8_t rdBuf[] = {0, 0, 0, 0, 0, 0, 0, 0}; //Jim debug, For Renesas requirements, I3C command: Continuously read R100~R107
+//Jim debug uint8_t rdBuf[] = {0};
uint8_t wrBuf[] = {0, 0};
int pmic = NUM_TO_PMIC(rank);
@@ -776,7 +886,7 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d
adcSelect[1] = rdBuf[0] & 0xbf; //Read current
wLen = 2;
}
-
+ rLen = 0; //Jim debug, For Renesas requirements, I3C write commands cannot be directly read; reading requires a separate I3C command.
ret = i3cWriteRead(i3cPmicName, adcSelect, wLen, rdBuf, rLen);
if (ret < 0)
{
@@ -785,19 +895,34 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d
std::this_thread::sleep_for(std::chrono::milliseconds(adcDelay[cpuid][rank]));
- for(int i=0; i<index; i++) {
- rLen = 1;
- rdBuf[0] = 0;
+
+ if(accStep31)
+ {
+ rLen = 8;
+ memset(rdBuf, 0, sizeof(rdBuf));
if(twoByteMode[cpuid][rank])
{
- wrBuf[0] = static_cast<uint8_t>(curOut[i] & 0xFF);
- wrBuf[1] = static_cast<uint8_t>((curOut[i] >> 8) & 0xFF);
+ wrBuf[0] = static_cast<uint8_t>(curOut[0] & 0xFF);
+ wrBuf[1] = static_cast<uint8_t>((curOut[0] >> 8) & 0xFF);
wLen = 2;
}
else
{
- wrBuf[0] = static_cast<uint8_t>(curOut[i]);
- wLen = 1;
+ if constexpr (debug)
+ {
+ std::cout << "twoByteMode[" << (int)cpuid << "][" << (int)rank << "] = "<< (int)twoByteMode[cpuid][rank] << std::endl;
+ }
+ if(pmicType[cpuid][rank] == PMIC5030)
+ {
+ return -1;
+ }
+ else
+ {
+ for(int i=0; i<6; i++)
+ {
+ dimmData.current[i] = calStep31CurPower(i, temp);
+ }
+ }
}
ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen);
@@ -805,24 +930,43 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d
{
return -1;
}
-
- if(accStep31)
- {
- temp[i] = rdBuf[0];
- }
- else
- {
- dimmData.current[i] = rdBuf[0] * 125.0 / 1000.0;
- }
- }
-
- if(accStep31)
- {
+ for(int i=0; i<index; i++) {
+ temp[i] = rdBuf[i];
+ }
+
for(int i=0; i<6; i++)
{
dimmData.current[i] = calStep31CurPower(i, temp);
}
}
+ else
+ {
+ for(int i=0; i<index; i++) {
+ rLen = 1;
+ rdBuf[0] = 0;
+ if(twoByteMode[cpuid][rank])
+ {
+ wrBuf[0] = static_cast<uint8_t>(curOut[i] & 0xFF);
+ wrBuf[1] = static_cast<uint8_t>((curOut[i] >> 8) & 0xFF);
+ wLen = 2;
+ }
+ else
+ {
+ wrBuf[0] = static_cast<uint8_t>(curOut[i]);
+ wLen = 1;
+ }
+
+ ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen);
+ if (ret < 0)
+ {
+ return -1;
+ }
+
+ dimmData.current[i] = rdBuf[0] * 125.0 / 1000.0;
+
+ }
+ }
+
//start to read power
if(twoByteMode[cpuid][rank])
@@ -835,7 +979,7 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d
adcSelect[1] |= 0x40;
wLen = 2;
}
-
+ rLen = 0; //Jim debug, For Renesas requirements, I3C write commands cannot be directly read; reading requires a separate I3C command.
ret = i3cWriteRead(i3cPmicName, adcSelect, wLen, rdBuf, rLen);
if (ret < 0)
{
@@ -844,19 +988,34 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d
std::this_thread::sleep_for(std::chrono::milliseconds(adcDelay[cpuid][rank]));
- for(int i=0; i<index; i++) {
- rLen = 1;
- rdBuf[0] = 0;
+ // For Renesas requirements, I3C command: Continuously read R100~R107
+ if(accStep31)
+ {
+ rLen = 8;
+ memset(rdBuf, 0, sizeof(rdBuf));
if(twoByteMode[cpuid][rank])
{
- wrBuf[0] = static_cast<uint8_t>(curOut[i] & 0xFF);
- wrBuf[1] = static_cast<uint8_t>((curOut[i] >> 8) & 0xFF);
+ wrBuf[0] = static_cast<uint8_t>(curOut[0] & 0xFF);
+ wrBuf[1] = static_cast<uint8_t>((curOut[0] >> 8) & 0xFF);
wLen = 2;
}
else
{
- wrBuf[0] = static_cast<uint8_t>(curOut[i]);
- wLen = 1;
+ if constexpr (debug)
+ {
+ std::cout << "twoByteMode[" << (int)cpuid << "][" << (int)rank << "] = "<< (int)twoByteMode[cpuid][rank] << std::endl;
+ }
+ if(pmicType[cpuid][rank] == PMIC5030)
+ {
+ return -1;
+ }
+ else
+ {
+ for(int i=0; i<6; i++)
+ {
+ dimmData.current[i] = calStep31CurPower(i, temp);
+ }
+ }
}
ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen);
@@ -864,24 +1023,42 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d
{
return -1;
}
-
- if(accStep31)
- {
- temp[i] = rdBuf[0];
- }
- else
- {
- dimmData.power[i] = rdBuf[0] * 125.0 / 1000.0;
- }
- }
-
- if(accStep31)
- {
- for(int i=0; i<STATUS_PMIC_RAIL_NUM; i++)
+ for(int i=0; i<index; i++) {
+ temp[i] = rdBuf[i];
+ }
+
+ for(int i=0; i<6; i++)
{
dimmData.power[i] = calStep31CurPower(i, temp);
}
}
+ else
+ {
+ for(int i=0; i<index; i++)
+ {
+ rLen = 1;
+ rdBuf[0] = 0;
+ if(twoByteMode[cpuid][rank])
+ {
+ wrBuf[0] = static_cast<uint8_t>(curOut[i] & 0xFF);
+ wrBuf[1] = static_cast<uint8_t>((curOut[i] >> 8) & 0xFF);
+ wLen = 2;
+ }
+ else
+ {
+ wrBuf[0] = static_cast<uint8_t>(curOut[i]);
+ wLen = 1;
+ }
+
+ ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen);
+ if (ret < 0)
+ {
+ return -1;
+ }
+ dimmData.power[i] = rdBuf[0] * 125.0 / 1000.0;
+
+ }
+ }
return 0;
}
@@ -994,7 +1171,7 @@ void DIMMSpdReader::readDimmInfo()
}
}
updateField(dimmName, TEMP, dData.temp, STATUS_TEMP_NUM);
-#if 0
+#if 1
if(regCounter == 0)
{
ret = getPmicStatusRegs(cpuid, i, dData);
--
2.34.1