From: Matthew Bettencourt <matthew.bettencourt@gmail.com>
To: linux@roeck-us.net
Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [BUG] SPD5118 Intermittent MR11 Corruption During Suspend/Resume
Date: Sun, 30 Aug 2026 18:21:46 -0500 [thread overview]
Message-ID: <1a8ea9da-1ac1-4312-a8ca-ea4a9f35093f@gmail.com> (raw)
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);
--- 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, ®val);
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;
}
next reply other threads:[~2026-08-30 23:21 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-30 23:21 Matthew Bettencourt [this message]
2026-08-31 15:12 ` [BUG] SPD5118 Intermittent MR11 Corruption During Suspend/Resume Guenter Roeck
2026-08-31 17:28 ` Guenter Roeck
2026-08-31 23:36 ` Matthew Bettencourt
[not found] ` <37132c40-aa82-4df1-b5ce-337601f3c085@gmail.com>
[not found] ` <3c4e9f59-5272-48cf-a4a0-eeefcba955a9@roeck-us.net>
2026-09-01 0:16 ` Matthew Bettencourt
2026-09-01 3:10 ` Guenter Roeck
2026-09-01 16:31 ` Matthew Bettencourt
2026-09-01 17:04 ` Guenter Roeck
2026-09-01 20:53 ` Matthew Bettencourt
2026-09-01 22:36 ` Guenter Roeck
2026-09-02 0:57 ` Matthew Bettencourt
2026-09-02 1:32 ` Guenter Roeck
2026-09-02 2:14 ` Matthew Bettencourt
2026-09-02 3:19 ` Guenter Roeck
2026-09-02 14:00 ` Matthew Bettencourt
2026-09-02 14:52 ` Guenter Roeck
2026-09-02 15:26 ` Matthew Bettencourt
2026-09-02 17:21 ` Guenter Roeck
2026-09-02 17:37 ` Matthew Bettencourt
2026-09-02 16:57 ` Armin Wolf
2026-09-02 17:08 ` Matthew Bettencourt
2026-09-02 17:22 ` Armin Wolf
2026-09-02 17:28 ` Matthew Bettencourt
2026-09-02 19:19 ` Armin Wolf
2026-09-02 19:25 ` Matthew Bettencourt
2026-09-02 19:31 ` Armin Wolf
2026-09-02 19:40 ` Matthew Bettencourt
2026-09-02 19:51 ` Armin Wolf
2026-09-03 18:01 ` Matthew Bettencourt
2026-09-03 18:16 ` Guenter Roeck
2026-09-03 18:25 ` Matthew Bettencourt
2026-09-03 21:05 ` Guenter Roeck
2026-09-03 22:47 ` Armin Wolf
2026-09-04 0:24 ` Matthew Bettencourt
2026-09-04 17:58 ` Guenter Roeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1a8ea9da-1ac1-4312-a8ca-ea4a9f35093f@gmail.com \
--to=matthew.bettencourt@gmail.com \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.