diff mbox series

[U-Boot] mmc: correct the HS400 initialization process

Message ID 20190318083059.32462-1-haibo.chen@nxp.com
State Superseded
Delegated to: Tom Rini
Headers show
Series [U-Boot] mmc: correct the HS400 initialization process | expand

Commit Message

Bough Chen March 18, 2019, 8:23 a.m. UTC
After the commit b9a2a0e2e9c0 ("mmc: Add support for downgrading
HS200/HS400 to HS mode"), it add a parameter in mmc_set_card_speed()
which indicates that the HS200/HS400 to HS downgrade is happening.

During the HS400 initialization, first select to HS200, and config
the related clock rate, then downgrade to HS mode. So here also need
to config the downgrade value to be true, make sure in the function
mmc_set_card_speed(), after switch to HS mode, first config the
clock rate, then read the EXT_CSD. Otherwise read EXT_CSD in HS mode
at wrong clock rate, e.g. 200MHz, may lead to uncertain result.

Test on i.MX8QM MEK board, some Micron eMMC will stuck in transfer
mode in this case, and USDHC will never get data transfer complete
status, cause the uboot hang.

Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
---
 drivers/mmc/mmc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

Comments

Marek Vasut March 18, 2019, 11:53 a.m. UTC | #1
On 3/18/19 9:23 AM, BOUGH CHEN wrote:
> After the commit b9a2a0e2e9c0 ("mmc: Add support for downgrading
> HS200/HS400 to HS mode"), it add a parameter in mmc_set_card_speed()
> which indicates that the HS200/HS400 to HS downgrade is happening.
> 
> During the HS400 initialization, first select to HS200, and config
> the related clock rate, then downgrade to HS mode. So here also need
> to config the downgrade value to be true, make sure in the function
> mmc_set_card_speed(), after switch to HS mode, first config the
> clock rate, then read the EXT_CSD. Otherwise read EXT_CSD in HS mode
> at wrong clock rate, e.g. 200MHz, may lead to uncertain result.

I think the fix is right, but the reasoning for it is not.

If you call mmc_set_card_speed() with hsdowngrade=true, it will result
in calling __mmc_switch() with send_status=false , which in turn means
that after issuing the MMC_CMD_SWITCH command, the code won't poll the
card using MMC_CMD_SEND_STATUS, but just wait a bit and then switch the
bus properties. This is indeed required when switching bus properties.
And that's what I think was making your card unstable.

Is that the case ?

> Test on i.MX8QM MEK board, some Micron eMMC will stuck in transfer
> mode in this case, and USDHC will never get data transfer complete
> status, cause the uboot hang.
> 
> Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
> ---
>  drivers/mmc/mmc.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 1c1527cc74..55d3560b30 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -1892,8 +1892,7 @@ static int mmc_select_hs400(struct mmc *mmc)
>  	}
>  
>  	/* Set back to HS */
> -	mmc_set_card_speed(mmc, MMC_HS, false);
> -	mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
> +	mmc_set_card_speed(mmc, MMC_HS, true);
>  
>  	err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
>  			 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
>
Bough Chen March 25, 2019, 10:24 a.m. UTC | #2
> -----Original Message-----
> From: Marek Vasut [mailto:marek.vasut@gmail.com]
> Sent: 2019年3月18日 19:53
> To: BOUGH CHEN <haibo.chen@nxp.com>; jh80.chung@samsung.com;
> trini@konsulko.com
> Cc: marek.vasut+renesas@gmail.com; Ye Li <ye.li@nxp.com>; dl-uboot-imx
> <uboot-imx@nxp.com>; u-boot@lists.denx.de
> Subject: Re: [PATCH] mmc: correct the HS400 initialization process
> 
> On 3/18/19 9:23 AM, BOUGH CHEN wrote:
> > After the commit b9a2a0e2e9c0 ("mmc: Add support for downgrading
> > HS200/HS400 to HS mode"), it add a parameter in mmc_set_card_speed()
> > which indicates that the HS200/HS400 to HS downgrade is happening.
> >
> > During the HS400 initialization, first select to HS200, and config the
> > related clock rate, then downgrade to HS mode. So here also need to
> > config the downgrade value to be true, make sure in the function
> > mmc_set_card_speed(), after switch to HS mode, first config the clock
> > rate, then read the EXT_CSD. Otherwise read EXT_CSD in HS mode at
> > wrong clock rate, e.g. 200MHz, may lead to uncertain result.
> 
> I think the fix is right, but the reasoning for it is not.
> 
> If you call mmc_set_card_speed() with hsdowngrade=true, it will result in
> calling __mmc_switch() with send_status=false , which in turn means that
> after issuing the MMC_CMD_SWITCH command, the code won't poll the card
> using MMC_CMD_SEND_STATUS, but just wait a bit and then switch the bus
> properties. This is indeed required when switching bus properties.
> And that's what I think was making your card unstable.
> 
> Is that the case ?

Sorry for the tardy reply, I miss the email last week.
No, if without this patch, even I add the dealy after the switch command, eMMC still stuck after the CMD8.
The main issue is that, in mmc_set_card_speed, if the bus mode the HS mode, it will send CMD8 to get the EXT_CSD, but the clock is still 200MHz at that time.
It is wrong that EMMC output data in HS mode at 200MHz. 

Best Regards
Haibo Chen

> 
> > Test on i.MX8QM MEK board, some Micron eMMC will stuck in transfer
> > mode in this case, and USDHC will never get data transfer complete
> > status, cause the uboot hang.
> >
> > Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
> > ---
> >  drivers/mmc/mmc.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index
> > 1c1527cc74..55d3560b30 100644
> > --- a/drivers/mmc/mmc.c
> > +++ b/drivers/mmc/mmc.c
> > @@ -1892,8 +1892,7 @@ static int mmc_select_hs400(struct mmc *mmc)
> >  	}
> >
> >  	/* Set back to HS */
> > -	mmc_set_card_speed(mmc, MMC_HS, false);
> > -	mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
> > +	mmc_set_card_speed(mmc, MMC_HS, true);
> >
> >  	err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
> EXT_CSD_BUS_WIDTH,
> >  			 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
> >
> 
> 
> --
> Best regards,
> Marek Vasut
Marek Vasut March 25, 2019, 11:16 a.m. UTC | #3
On 3/25/19 11:24 AM, BOUGH CHEN wrote:
> 
>> -----Original Message-----
>> From: Marek Vasut [mailto:marek.vasut@gmail.com]
>> Sent: 2019年3月18日 19:53
>> To: BOUGH CHEN <haibo.chen@nxp.com>; jh80.chung@samsung.com;
>> trini@konsulko.com
>> Cc: marek.vasut+renesas@gmail.com; Ye Li <ye.li@nxp.com>; dl-uboot-imx
>> <uboot-imx@nxp.com>; u-boot@lists.denx.de
>> Subject: Re: [PATCH] mmc: correct the HS400 initialization process
>>
>> On 3/18/19 9:23 AM, BOUGH CHEN wrote:
>>> After the commit b9a2a0e2e9c0 ("mmc: Add support for downgrading
>>> HS200/HS400 to HS mode"), it add a parameter in mmc_set_card_speed()
>>> which indicates that the HS200/HS400 to HS downgrade is happening.
>>>
>>> During the HS400 initialization, first select to HS200, and config the
>>> related clock rate, then downgrade to HS mode. So here also need to
>>> config the downgrade value to be true, make sure in the function
>>> mmc_set_card_speed(), after switch to HS mode, first config the clock
>>> rate, then read the EXT_CSD. Otherwise read EXT_CSD in HS mode at
>>> wrong clock rate, e.g. 200MHz, may lead to uncertain result.
>>
>> I think the fix is right, but the reasoning for it is not.
>>
>> If you call mmc_set_card_speed() with hsdowngrade=true, it will result in
>> calling __mmc_switch() with send_status=false , which in turn means that
>> after issuing the MMC_CMD_SWITCH command, the code won't poll the card
>> using MMC_CMD_SEND_STATUS, but just wait a bit and then switch the bus
>> properties. This is indeed required when switching bus properties.
>> And that's what I think was making your card unstable.
>>
>> Is that the case ?
> 
> Sorry for the tardy reply, I miss the email last week.
> No, if without this patch, even I add the dealy after the switch command, eMMC still stuck after the CMD8.
> The main issue is that, in mmc_set_card_speed, if the bus mode the HS mode, it will send CMD8 to get the EXT_CSD, but the clock is still 200MHz at that time.
> It is wrong that EMMC output data in HS mode at 200MHz. 

OK, that makes sense.
Tom Rini March 25, 2019, 12:10 p.m. UTC | #4
On Mon, Mar 25, 2019 at 12:16:53PM +0100, Marek Vasut wrote:
> On 3/25/19 11:24 AM, BOUGH CHEN wrote:
> > 
> >> -----Original Message-----
> >> From: Marek Vasut [mailto:marek.vasut@gmail.com]
> >> Sent: 2019年3月18日 19:53
> >> To: BOUGH CHEN <haibo.chen@nxp.com>; jh80.chung@samsung.com;
> >> trini@konsulko.com
> >> Cc: marek.vasut+renesas@gmail.com; Ye Li <ye.li@nxp.com>; dl-uboot-imx
> >> <uboot-imx@nxp.com>; u-boot@lists.denx.de
> >> Subject: Re: [PATCH] mmc: correct the HS400 initialization process
> >>
> >> On 3/18/19 9:23 AM, BOUGH CHEN wrote:
> >>> After the commit b9a2a0e2e9c0 ("mmc: Add support for downgrading
> >>> HS200/HS400 to HS mode"), it add a parameter in mmc_set_card_speed()
> >>> which indicates that the HS200/HS400 to HS downgrade is happening.
> >>>
> >>> During the HS400 initialization, first select to HS200, and config the
> >>> related clock rate, then downgrade to HS mode. So here also need to
> >>> config the downgrade value to be true, make sure in the function
> >>> mmc_set_card_speed(), after switch to HS mode, first config the clock
> >>> rate, then read the EXT_CSD. Otherwise read EXT_CSD in HS mode at
> >>> wrong clock rate, e.g. 200MHz, may lead to uncertain result.
> >>
> >> I think the fix is right, but the reasoning for it is not.
> >>
> >> If you call mmc_set_card_speed() with hsdowngrade=true, it will result in
> >> calling __mmc_switch() with send_status=false , which in turn means that
> >> after issuing the MMC_CMD_SWITCH command, the code won't poll the card
> >> using MMC_CMD_SEND_STATUS, but just wait a bit and then switch the bus
> >> properties. This is indeed required when switching bus properties.
> >> And that's what I think was making your card unstable.
> >>
> >> Is that the case ?
> > 
> > Sorry for the tardy reply, I miss the email last week.
> > No, if without this patch, even I add the dealy after the switch command, eMMC still stuck after the CMD8.
> > The main issue is that, in mmc_set_card_speed, if the bus mode the HS mode, it will send CMD8 to get the EXT_CSD, but the clock is still 200MHz at that time.
> > It is wrong that EMMC output data in HS mode at 200MHz. 
> 
> OK, that makes sense.

Do we need a re-worded commit message then or no?  Thanks!
Marek Vasut March 25, 2019, 12:28 p.m. UTC | #5
On 3/25/19 1:10 PM, Tom Rini wrote:
> On Mon, Mar 25, 2019 at 12:16:53PM +0100, Marek Vasut wrote:
>> On 3/25/19 11:24 AM, BOUGH CHEN wrote:
>>>
>>>> -----Original Message-----
>>>> From: Marek Vasut [mailto:marek.vasut@gmail.com]
>>>> Sent: 2019年3月18日 19:53
>>>> To: BOUGH CHEN <haibo.chen@nxp.com>; jh80.chung@samsung.com;
>>>> trini@konsulko.com
>>>> Cc: marek.vasut+renesas@gmail.com; Ye Li <ye.li@nxp.com>; dl-uboot-imx
>>>> <uboot-imx@nxp.com>; u-boot@lists.denx.de
>>>> Subject: Re: [PATCH] mmc: correct the HS400 initialization process
>>>>
>>>> On 3/18/19 9:23 AM, BOUGH CHEN wrote:
>>>>> After the commit b9a2a0e2e9c0 ("mmc: Add support for downgrading
>>>>> HS200/HS400 to HS mode"), it add a parameter in mmc_set_card_speed()
>>>>> which indicates that the HS200/HS400 to HS downgrade is happening.
>>>>>
>>>>> During the HS400 initialization, first select to HS200, and config the
>>>>> related clock rate, then downgrade to HS mode. So here also need to
>>>>> config the downgrade value to be true, make sure in the function
>>>>> mmc_set_card_speed(), after switch to HS mode, first config the clock
>>>>> rate, then read the EXT_CSD. Otherwise read EXT_CSD in HS mode at
>>>>> wrong clock rate, e.g. 200MHz, may lead to uncertain result.
>>>>
>>>> I think the fix is right, but the reasoning for it is not.
>>>>
>>>> If you call mmc_set_card_speed() with hsdowngrade=true, it will result in
>>>> calling __mmc_switch() with send_status=false , which in turn means that
>>>> after issuing the MMC_CMD_SWITCH command, the code won't poll the card
>>>> using MMC_CMD_SEND_STATUS, but just wait a bit and then switch the bus
>>>> properties. This is indeed required when switching bus properties.
>>>> And that's what I think was making your card unstable.
>>>>
>>>> Is that the case ?
>>>
>>> Sorry for the tardy reply, I miss the email last week.
>>> No, if without this patch, even I add the dealy after the switch command, eMMC still stuck after the CMD8.
>>> The main issue is that, in mmc_set_card_speed, if the bus mode the HS mode, it will send CMD8 to get the EXT_CSD, but the clock is still 200MHz at that time.
>>> It is wrong that EMMC output data in HS mode at 200MHz. 
>>
>> OK, that makes sense.
> 
> Do we need a re-worded commit message then or no?  Thanks!

A bit wouldn't hurt, to clarify things.
diff mbox series

Patch

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 1c1527cc74..55d3560b30 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1892,8 +1892,7 @@  static int mmc_select_hs400(struct mmc *mmc)
 	}
 
 	/* Set back to HS */
-	mmc_set_card_speed(mmc, MMC_HS, false);
-	mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
+	mmc_set_card_speed(mmc, MMC_HS, true);
 
 	err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
 			 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);