From: Guenter Roeck <linux@roeck-us.net>
To: Matthew Bettencourt <matthew.bettencourt@gmail.com>
Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [BUG] SPD5118 Intermittent MR11 Corruption During Suspend/Resume
Date: Mon, 31 Aug 2026 08:12:44 -0700 [thread overview]
Message-ID: <ee284272-0da0-45b6-a3be-c76822e5d54f@roeck-us.net> (raw)
In-Reply-To: <1a8ea9da-1ac1-4312-a8ca-ea4a9f35093f@gmail.com>
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, ®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 prev parent reply other threads:[~2026-08-31 15:12 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-30 23:21 Matthew Bettencourt
2026-08-31 15:12 ` Guenter Roeck [this message]
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=ee284272-0da0-45b6-a3be-c76822e5d54f@roeck-us.net \
--to=linux@roeck-us.net \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=matthew.bettencourt@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®