Re: [PATCH] mmc: core: Kioxia 016G01 does not enter boot mode after SLEEP
From: Ulf Hansson
Date: Thu Jun 18 2026 - 11:18:32 EST
On Thu, Jun 18, 2026 at 12:23 PM Florian Fainelli
<florian.fainelli@xxxxxxxxxxxx> wrote:
>
>
>
> On 6/17/2026 2:49 AM, Ulf Hansson wrote:
> > On Tue, Jun 16, 2026 at 8:58 PM Kamal Dasu <kamal.dasu@xxxxxxxxxxxx> wrote:
> >>
> >>
> >>
> >> On Thu, Jun 11, 2026 at 5:53 PM Ulf Hansson <ulf.hansson@xxxxxxxxxxxxxxxx> wrote:
> >>>
> >>> On Tue, May 19, 2026 at 5:27 AM Florian Fainelli
> >>> <florian.fainelli@xxxxxxxxxxxx> wrote:
> >>>>
> >>>> On 5/12/26 06:33, Ulf Hansson wrote:
> >>>>> On Mon, 11 May 2026 at 18:01, Florian Fainelli
> >>>>> <florian.fainelli@xxxxxxxxxxxx> wrote:
> >>>>>>
> >>>>>> On 5/11/26 07:18, Ulf Hansson wrote:
> >>>>>>> On Mon, 13 Apr 2026 at 20:06, Florian Fainelli
> >>>>>>> <florian.fainelli@xxxxxxxxxxxx> wrote:
> >>>>>>>>
> >>>>>>>> The Kioxia 016G01 eMMC device does not exit SLEEP mode when sending CMD0
> >>>>>>>> which prevents the system from properly resuming from S3 warm boot where
> >>>>>>>> the eMMC is necessary to pull in the boot components.
> >>>>>>>
> >>>>>>> Is the bug confirmed by Kioxia?
> >>>>>>
> >>>>>> We've been going back and forth with them without much progress as far
> >>>>>> as a resolution goes. Since there was no progress and I would like to
> >>>>>> get this included in downstream kernels at some point, this was submitted.
> >>>>>>
> >>>>>>>
> >>>>>>> If not, can you explain a bit more what is actually happening during
> >>>>>>> system resume?
> >>>>>>
> >>>>>> Upon entering Suspend-to-DRAM, the eMMC will be put into sleep mode.
> >>>>>> When our systems resume, one of our hardware cores driving the eMMC (HIF
> >>>>>> block) in command mode will send a CMD0 command for the eMMC device to
> >>>>>
> >>>>> Is the CMD0 sent solely by HW/FW before the mmc core executes
> >>>>> _mmc_resume() during system resume?
> >>>>
> >>>> That is correct. The sequence basically goes like this: HW sends CMD0,
> >>>> then FW pulls in boot code, identifies this is a Suspend to DRAM, does
> >>>> its steps, and eventually Linux resumes and calls _mmc_resume().
> >>>
> >>> Okay, so it seems like this problem boils down to the fact that the FW
> >>> decides to send a CMD0 command for no good reason at system resume.
> >>> Unless I am missing a point here?
> >>>
> >> The JEDEC JESD84-B51 boot sequence is normative.
> >> The host sends CMD0 (0xF0F0F0F0 / GO_PRE_IDLE_STATE) to enter pre-idle/boot mode
> >> Broadcom mmc controller does not skip CMD0 and has no knowledge of the power
> >> State that the kernel left the device; it runs before DRAM is initialized and before Linux resumes,
> >> before any kernel state is accessible.
> >
> > I understand the CMD0 generally works to wakeup/initialize the eMMC,
> > but that isn't really sufficient.
> >
> > Please, consider these scenarios:
> > 1) If the kernel decides to turn off clocks/regulators (VCC/VCCQ) at
> > suspend for the eMMC, then how does the FW know that it needs to
> > restore these before sending CMD0?
>
> If we had such capability on our board designs, then we would make sure
> that there is adequate power sequencing within the board design to
> guarantee that the eMMC device gets powered back on upon resuming from
> warm boot. We have a variety of signals that can be wired-OR to relevant
> discrete chips, or use an external PMIC to achieve that goal. Your point
> is well understood and valid in general, but not applicable in our case
> here.
>
> > 2) At resume the kernel wants to wake up the eMMC by sending a CMD5
> > (awake) instead of CMD0 (not implemented, but since it is faster we
> > may decide to add this at some point). If the FW already sent CMD0, a
> > CMD5 path would fail.
>
> That assumes the kernel is the first entity involved in interfacing with
> the eMMC device, but that is not the case for us, see below.
>
> >
> >>
> >>
> >>>
> >>> The problem is that the FW doesn't know what low power state the
> >>> kernel decided to put the eMMC device into at system suspend, hence it
> >>> should really leave the decision to the kernel to wake up the eMMC at
> >>> system resume.
> >>>
> >>> Would it be possible to fix the FW instead?
>
> This is not an option for us, see below as to why.
>
> >>>
> >>>>
> >>>>>
> >>>>>> exit SLEEP mode. The Kioxia 016G01 device takes 10ms rather than the
> >>>>>> tSLEEP_EXIT value of 1ms which is advertised and so our HIF block does
> >>>>>
> >>>>> Can you please clarify what tSLEEP_EXIT refers to? Are you referring
> >>>>> to the S_A_TIMEOUT in the EXT_CSD register for the eMMC card?
> >>>>
> >>>> Yes, sorry I am referring to S_A_TIMEOUT in the EXT_CSD register.
> >>>>
> >>>>>
> >>>>> Anyway, waking up an eMMC from sleep state in just 1ms sounds a bit
> >>>>> optimistic to me.
> >>>>
> >>>> Fair enough, but AFAIR we wait up to 30ms before declaring a timeout,
> >>>> every other vendor we have seen exits and acknowledges boot within
> >>>> 1-10ms at most. Similarly if the device is not in SLEEP, then it
> >>>> acknowledges boot within 1ms.
> >>>
> >>> The S_A_TIMEOUT specifies the time the eMMC needs to complete the wake
> >>> up from its sleep state.
> >>>
> >>> If the device isn't in sleep state but fully powered-on (as it seems
> >>> to be what you have been playing with), the eMMC should just respond
> >>> immediately as with any other command when the eMMC is in "TRAN"
> >>> state. I assume that's why it works if we don't send the CMD5 (sleep)
> >>> command at system suspend.
> >>>
> >>>>
> >>>>>
> >>>>>> not see the Boot ACK pattern in time and does not service the read
> >>>>>> request from the processor that wanted to read from eMMC, we get a reset
> >>>>>> of the system, rather than continue booting.
> >>>>>>
> >>>>>> When SLEEP is not enabled, the eMMC device responds within tSLEEP_EXIT
> >>>>>> as advertised and we don't have that problem.
> >>>>>
> >>>>> Okay, I see.
> >>>>>
> >>>>> In this regard, it's important to understand for me how the mmc host
> >>>>> driver (and the HW/FW) manages VCC and VCCQ when the mmc core calls
> >>>>> mmc_power_off() from _mmc_suspend()?
> >>>>>
> >>>>> Does this turn off any of these regulators or what happens to them
> >>>>> during system suspend?
> >>>>
> >>>> We don't have software controlled regulators for VCC and VCCQ and our
> >>>> reference boards using that specific eMMC device keep it powered on
> >>>> through suspend-to-DRAM. This is the very reason why if it stays in
> >>>> sleep mode, powered on, and then we attempt to boot from eMMC we have
> >>>> this issue.
> >>>
> >>> Okay, thanks for elaborating.
> >>>
> >>> So you are mixing the system suspend/resume scenarios with boot here.
> >>> Is the problem for both?
> >>>
> >> No the problem only occurs when we suspend/resume if we put the device in suspend as per spec,
> >> subsequent resume fails.
> >
> > Okay, thanks for clarifying!
> >
> >>
> >>>
> >>> I understand the timeout problem, but not why the FW needs to send the
> >>> CMD0 to wake up the eMMC from system suspend. In regards to boot, that
> >>> is an entirely different scenario.
> >>>
> >>
> >> Vendor datasheets implementing JESD84-B51 quote from spec :
> >> "In the Sleep state, the power consumption of the memory device is minimized.
> >> In this state, the memory device reacts only to the commands RESET (CMD0 with
> >> argument of either 0x00000000 or 0xF0F0F0F0 or H/W reset) and SLEEP/AWAKE
> >> (CMD5). All other commands are ignored by the memory device."
> >
> > Yes, that's correct but doesn't explain why the FW needs to send CMD0,
> > rather than relying on the kernel to do it.
>
> See below.
>
> >
> >>
> >>> Does the FW need to read something from the eMMC before the system
> >>> resumes? Or that is just during boot?
> >>
> >>
> >> It's just booting up on resume and reads bootcode.
> >
> > Would you mind elaborating what "reads bootcode" really means here? Is
> > it reading data from the eMMC?
>
> We have a boot ROM masked within the chip that interfaces with the Host
> Interface (HIF) controller which drives the eMMC in boot mode in order
> to allow the boot ROM code to pull in the subsequent boot components. If
> that first access fails because the eMMC device is still asleep then
> that boot ROM considers it a fatal error and will issue a chip reset.
> From there on, this is no longer a warm boot, but now a cold boot
> because the reset reason changed. From a system architecture
> perspective, a warm boot is similar to a cold boot except:
>
> - there is a reset controller bit indicating this is a wake-up from what
> we call S3, rather than a cold boot
>
> - DDR contents are guaranteed to be preserved by having kept the
> supplies on, therefore we can restore SW/FW states
>
> - there is additionally an on-chip memory RAM that can store persistent
> information, too
>
> - first stage boot loader identifies the warm boot condition and then
> proceeds with restoring DRAM calibration parameters, and then hands off
> control to the remaining FW/SW running on the system. Eventually Linux
> resumes and can interface with the eMMC controller
>
> >
> > To me, it looks like we may have two ways forward to fix this problem:
> > 1) Fix the FW so it doesn't need to send the CMD0 at resume. If that
> > is possible, this would be the best option.
>
> That is not an option for us because the
>
> > 2) Instruct the kernel to keep the eMMC powered on at suspend, while
> > still doing a regular re-initialization of it at resume.
>
> OK, so your angle is that we should not focus on the kernel sending the
> SLEEP command, but instead have a notion of "keep eMMC device
> always-on", which would also tentatively address a board design where we
> could turn off the eMMC device voltage regulators?
Thanks for all the details!
Yes, keeping the eMMC device always-on seems to do exactly what we
want. Although, since the FW sends a CMD0, we need to re-initialize
the eMMC from the kernel point of view, at system resume.
So, let's move away from the card quirk and invent a new mmc host cap
bit that instucts the mmc core what to do here instead. Not sure if
this a DT based platform, but if so, we may also to want to add a
corresponding dt property, unless the mmc host cap bit can be derived
from a compatible string.
Kind regards
Uffe