Re: [BUG] SPD5118 Intermittent MR11 Corruption During Suspend/Resume

From: Guenter Roeck

Date: Mon Aug 31 2026 - 14:40:29 EST


On 8/30/26 16:21, Matthew Bettencourt wrote:
Hello,

I believe I have identified a bug in the spd5118 driver's suspend/resume cycle where register MR11 (0x0B) becomes corrupted and set to 0x08 during spd5118_suspend().

Upon system wake, MR11 remains set to 0x08. This persists across warm reboots, causing the motherboard BIOS and OS to incorrectly identify a 32GB DIMM as only 2GB after a warm reboot. A complete cold power cycle clears MR11 back to 0x00, after which the system correctly detects the full 32GB capacity again. Blacklisting the spd5118 driver prevents the issue entirely.

To troubleshoot, I instrumented the spd5118 driver to log both the cached and physical values of MR11 before and after key function calls during suspend and resume. The corruption occurs during the regmap_update_bits() call (~lines 505–506):

regmap_update_bits(regmap, SPD5118_REG_TEMP_CONFIG,
                   SPD5118_TS_DISABLE, SPD5118_TS_DISABLE);


That is a write to SPD5118_REG_TEMP_CONFIG, which is MR26, not MR11.
I would agree that a write to MR11 would be fatal, even mode so
writing 0x08 which changes the legacy mode bit and, yes, doing so
would be fatal.

Can you also add a debug log to spd5118_nvmem_read() ? I wonder
if that could trigger writes to MR11 through regmap. That should
not touch bit 3 of MR11, but who knows.

Thanks,
Guenter

--- System Information ---
System info:Motherboard: ASRock X870 Pro-A WiFi (UEFI v4.43)
CPU: AMD Ryzen 7 9800X3D
RAM: 64GB (2x32GB) G.Skill DDR5 (Part: F5-6400J3239G32G)
Kernel: 7.2.0-1-default (openSUSE Tumbleweed)
SMBus Controller: AMD PIIX4 (i2c-piix4 / bus i2c-12)

--- Testing and Logs ---
Logging captured via dmesg shows:
[  277.569950] [    T113] i2c i2c-12: Transaction (pre): CNT=08, CMD=1a, ADD=a7, DAT0=00, DAT1=18
[  277.570507] [    T113] i2c i2c-12: Transaction (post): CNT=08, CMD=1a, ADD=a7, DAT0=00, DAT1=18
[  277.570594] [   T3293] i2c i2c-12: Transaction (pre): CNT=08, CMD=1a, ADD=a3, DAT0=00, DAT1=18
[  277.571150] [   T3293] i2c i2c-12: Transaction (post): CNT=08, CMD=1a, ADD=a3, DAT0=00, DAT1=18
[  277.571226] [    T113] i2c i2c-12: Transaction (pre): CNT=08, CMD=0b, ADD=a7, DAT0=00, DAT1=18
[  277.572067] [    T113] i2c i2c-12: Transaction (post): CNT=08, CMD=0b, ADD=a7, DAT0=00, DAT1=18
[  277.572082] [    T113] spd5118 12-0053: PRE BIT UPDATE: SUSPEND MR11 (0x0B) -> Cache: 0x00 | Bus: 0x00
[  277.572142] [   T3293] i2c i2c-12: Transaction (pre): CNT=08, CMD=0b, ADD=a3, DAT0=00, DAT1=18
[  277.573073] [   T3293] i2c i2c-12: Transaction (post): CNT=08, CMD=0b, ADD=a3, DAT0=00, DAT1=18
[  277.573085] [   T3293] spd5118 12-0051: PRE BIT UPDATE: SUSPEND MR11 (0x0B) -> Cache: 0x00 | Bus: 0x00
[  277.573140] [    T113] i2c i2c-12: Transaction (pre): CNT=08, CMD=0b, ADD=a7, DAT0=00, DAT1=18
[  277.574063] [    T113] i2c i2c-12: Transaction (post): CNT=08, CMD=0b, ADD=a7, DAT0=00, DAT1=18
[  277.574130] [   T3293] i2c i2c-12: Transaction (pre): CNT=08, CMD=0b, ADD=a3, DAT0=00, DAT1=18
[  277.575552] [   T3293] i2c i2c-12: Transaction (post): CNT=08, CMD=01, ADD=45, DAT0=ff, DAT1=18
[  277.575617] [    T113] i2c i2c-12: Transaction (pre): CNT=08, CMD=1a, ADD=a7, DAT0=ff, DAT1=18
[  277.576169] [    T113] i2c i2c-12: Transaction (post): CNT=08, CMD=1a, ADD=a7, DAT0=00, DAT1=18
[  277.576237] [   T3293] i2c i2c-12: Transaction (pre): CNT=08, CMD=0b, ADD=a2, DAT0=f8, DAT1=18
[  277.577061] [   T3293] i2c i2c-12: Transaction (post): CNT=08, CMD=0b, ADD=a2, DAT0=f8, DAT1=18
[  277.577121] [    T113] i2c i2c-12: Transaction (pre): CNT=08, CMD=0b, ADD=a7, DAT0=f8, DAT1=18
[  277.578063] [    T113] i2c i2c-12: Transaction (post): CNT=08, CMD=0b, ADD=a7, DAT0=00, DAT1=18
[  277.578127] [   T3293] i2c i2c-12: Transaction (pre): CNT=08, CMD=1a, ADD=a3, DAT0=00, DAT1=18
[  277.579062] [   T3293] i2c i2c-12: Transaction (post): CNT=08, CMD=1a, ADD=a3, DAT0=00, DAT1=18
[  277.579131] [    T113] i2c i2c-12: Transaction (pre): CNT=08, CMD=1a, ADD=a6, DAT0=01, DAT1=18
[  277.579560] [    T113] i2c i2c-12: Transaction (post): CNT=08, CMD=1a, ADD=a6, DAT0=01, DAT1=18
[  277.579620] [   T3293] i2c i2c-12: Transaction (pre): CNT=08, CMD=0b, ADD=a3, DAT0=01, DAT1=18
[  277.580170] [   T3293] i2c i2c-12: Transaction (post): CNT=08, CMD=0b, ADD=a3, DAT0=08, DAT1=18
[  277.580234] [    T113] i2c i2c-12: Transaction (pre): CNT=08, CMD=0b, ADD=a7, DAT0=08, DAT1=18
[  277.581061] [    T113] i2c i2c-12: Transaction (post): CNT=08, CMD=0b, ADD=a7, DAT0=00, DAT1=18
[  277.581072] [    T113] spd5118 12-0053: POST BIT UPDATE: SUSPEND MR11 (0x0B) -> Cache: 0x00 | Bus: 0x00
[  277.581128] [   T3293] i2c i2c-12: Transaction (pre): CNT=08, CMD=1a, ADD=a2, DAT0=01, DAT1=18
[  277.581559] [   T3293] i2c i2c-12: Transaction (post): CNT=08, CMD=1a, ADD=a2, DAT0=01, DAT1=18
[  277.581626] [   T3293] i2c i2c-12: Transaction (pre): CNT=08, CMD=0b, ADD=a3, DAT0=01, DAT1=18
[  277.582236] [   T3293] i2c i2c-12: Transaction (post): CNT=08, CMD=0b, ADD=a3, DAT0=08, DAT1=18
[  277.582250] [   T3293] spd5118 12-0051: POST BIT UPDATE: SUSPEND MR11 (0x0B) -> Cache: 0x00 | Bus: 0x08


--- The logs that are of interest ---
[  277.573085] [   T3293] spd5118 12-0051: PRE BIT UPDATE: SUSPEND MR11 (0x0B) -> Cache: 0x00 | Bus: 0x00



[  277.582250] [   T3293] spd5118 12-0051: POST BIT UPDATE: SUSPEND MR11 (0x0B) -> Cache: 0x00 | Bus: 0x08

I enabled i2c debugging as well in case it helps. The lines I focusing on are “PRE BIT UPDATE…” and “POST BIT UPDATE…”, immediately after regmap_update_bits() the physical bus value for MR11 shifts to 0x08 while the regmap cache remains 0x00.

I looked through the history of spd5118 patches and bugs and noticed there has been some issues around suspend and sleep cycles. This might be a deeper issue than just the spd5118 driver.

Additional Notes:
- Intermittent Nature: The issue is intermittent and typically reproduces within ~10 sleep/resume cycles.

- Single DIMM Testing: I was unable to reproduce the issue with only 1 DIMM installed after running over 30 sleep/resume cycles, though the intermittent nature makes it hard to rule out entirely.

- Hardware Health: Memory stability was verified with a varitey of memory tests with zero errors. Issue occurs with JEDEC and XMP profiles enabled


--- Steps to Reproduce ---
1. Boot system from cold boot. Load the spd5118 driver.
2. Put system to sleep
3. Wake system
4. Check value of MR11, if corrupted warm reboot go to step 7
6. Go to step 2, repeat
7. System now shows corrupted DIMM with a size of 2GB

--- My test spd5118_suspend function ---
static int spd5118_suspend(struct device *dev)
{
 struct spd5118_data *data = dev_get_drvdata(dev);
 struct regmap *regmap = data->regmap;
 u32 cache_val = 0, bus_val = 0;
 u32 regval;
 int err;

 err = regmap_read(regmap, SPD5118_REG_TEMP_CONFIG, &regval);
 if (err < 0)
 return err;


 /* 1. Read cached MR11 value from RAM */
 regmap_read(regmap, SPD5118_REG_I2C_LEGACY_MODE, &cache_val);

 /* 2. Read physical MR11 value directly from I2C bus */
 regcache_cache_bypass(regmap, true);
 regmap_read(regmap, SPD5118_REG_I2C_LEGACY_MODE, &bus_val);
 regcache_cache_bypass(regmap, false);

 /* 3. Output both on the exact same log line */
 dev_info(dev, "PRE BIT UPDATE: SUSPEND MR11 (0x0B) -> Cache: 0x%02x | Bus: 0x%02x\n", cache_val, bus_val);

 regcache_cache_bypass(regmap, true);
 regmap_update_bits(regmap, SPD5118_REG_TEMP_CONFIG, SPD5118_TS_DISABLE,
 SPD5118_TS_DISABLE);
 regcache_cache_bypass(regmap, false);

 /* 1. Read cached MR11 value from RAM */
 regmap_read(regmap, SPD5118_REG_I2C_LEGACY_MODE, &cache_val);

    /* 2. Read physical MR11 value directly from I2C bus */
    regcache_cache_bypass(regmap, true);
    regmap_read(regmap, SPD5118_REG_I2C_LEGACY_MODE, &bus_val);
    regcache_cache_bypass(regmap, false);

    /* 3. Output both on the exact same log line */
    dev_info(dev, "POST BIT UPDATE: SUSPEND MR11 (0x0B) -> Cache: 0x%02x | Bus: 0x%02x\n", cache_val, bus_val);

    regcache_cache_only(regmap, true);
    regcache_mark_dirty(regmap);

    return 0;
}