[v2, 06/11] mmc: add a mmc_hs400_prepare_ddr() interface

Y.b. Lu yangbo.lu at nxp.com
Mon Jul 20 09:46:50 CEST 2020


Hi Peng,

> -----Original Message-----
> From: Peng Fan <peng.fan at nxp.com>
> Sent: Monday, July 20, 2020 9:40 AM
> To: Y.b. Lu <yangbo.lu at nxp.com>; u-boot at lists.denx.de; Priyanka Jain
> <priyanka.jain at nxp.com>; 'Jaehoon Chung' <jh80.chung at samsung.com>
> Cc: Y.b. Lu <yangbo.lu at nxp.com>
> Subject: RE: [v2, 06/11] mmc: add a mmc_hs400_prepare_ddr() interface
> 
> > Subject: [v2, 06/11] mmc: add a mmc_hs400_prepare_ddr() interface
> >
> > Add a mmc_hs400_prepare_ddr() interface for controllers which needs
> > preparation before switching to DDR mode for
> > HS400 mode.
> 
> This is LSx specific? If yes, could this be done in fsl_esdhc.c?

Yes. Actually I desire to put these esdhc specific setting in its own driver too.
However the HS400 procedure of esdhc indeed break the standard process.
As you see in my patch #7 commit message, the tuning block has to be disabled after switching to HS and before switching to DDR.

> 3. Switch to High Speed mode and then set the card clock frequency to
>    a value not greater than 52Mhz
> 4. Clear TBCTL[TB_EN],tuning block enable bit.
> 5. Change to 8 bit DDR Mode

I have to make code changed as below expecting some controllers drivers may utilize mmc_hs400_prepare_ddr() too.
We had done same thing in linux too. (cc14eec mmc: core: Add ->hs400_prepare_ddr() callback)
Do you have any suggestion?

mmc_set_card_speed(mmc, MMC_HS, true);

+	mmc_hs400_prepare_ddr(mmc);
+
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
               EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);

Thanks.

> 
> Thanks,
> Peng.
> 
> >
> > Signed-off-by: Yangbo Lu <yangbo.lu at nxp.com>
> > ---
> > Changes for v2:
> > 	- None.
> > ---
> >  drivers/mmc/mmc-uclass.c | 15 +++++++++++++++
> >  drivers/mmc/mmc.c        |  2 ++
> >  include/mmc.h            | 15 ++++++++++++++-
> >  3 files changed, 31 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index
> > b9f0880..240b205 100644
> > --- a/drivers/mmc/mmc-uclass.c
> > +++ b/drivers/mmc/mmc-uclass.c
> > @@ -141,6 +141,21 @@ int mmc_set_enhanced_strobe(struct mmc
> > *mmc)  }  #endif
> >
> > +int dm_mmc_hs400_prepare_ddr(struct udevice *dev) {
> > +	struct dm_mmc_ops *ops = mmc_get_ops(dev);
> > +
> > +	if (ops->hs400_prepare_ddr)
> > +		return ops->hs400_prepare_ddr(dev);
> > +
> > +	return 0;
> > +}
> > +
> > +int mmc_hs400_prepare_ddr(struct mmc *mmc) {
> > +	return dm_mmc_hs400_prepare_ddr(mmc->dev);
> > +}
> > +
> >  int dm_mmc_host_power_cycle(struct udevice *dev)  {
> >  	struct dm_mmc_ops *ops = mmc_get_ops(dev); diff --git
> > a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index a18e75d..e396207
> > 100644
> > --- a/drivers/mmc/mmc.c
> > +++ b/drivers/mmc/mmc.c
> > @@ -1987,6 +1987,8 @@ static int mmc_select_hs400(struct mmc *mmc)
> >  	/* Set back to HS */
> >  	mmc_set_card_speed(mmc, MMC_HS, true);
> >
> > +	mmc_hs400_prepare_ddr(mmc);
> > +
> >  	err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
> > EXT_CSD_BUS_WIDTH,
> >  			 EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
> >  	if (err)
> > diff --git a/include/mmc.h b/include/mmc.h index 2399cc2..659df75 100644
> > --- a/include/mmc.h
> > +++ b/include/mmc.h
> > @@ -513,6 +513,14 @@ struct dm_mmc_ops {
> >  	 * @return maximum number of blocks for this transfer
> >  	 */
> >  	int (*get_b_max)(struct udevice *dev, void *dst, lbaint_t blkcnt);
> > +
> > +	/**
> > +	 * hs400_prepare_ddr - prepare to switch to DDR mode
> > +	 *
> > +	 * @dev:	Device to check
> > +	 * @return 0 if success, -ve on error
> > +	 */
> > +	int (*hs400_prepare_ddr)(struct udevice *dev);
> >  };
> >
> >  #define mmc_get_ops(dev)        ((struct dm_mmc_ops
> > *)(dev)->driver->ops)
> > @@ -540,7 +548,7 @@ int mmc_host_power_cycle(struct mmc *mmc);
> int
> > mmc_deferred_probe(struct mmc *mmc);  int mmc_reinit(struct mmc
> > *mmc);  int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt);
> > -
> > +int mmc_hs400_prepare_ddr(struct mmc *mmc);
> >  #else
> >  struct mmc_ops {
> >  	int (*send_cmd)(struct mmc *mmc,
> > @@ -552,6 +560,11 @@ struct mmc_ops {
> >  	int (*host_power_cycle)(struct mmc *mmc);
> >  	int (*get_b_max)(struct mmc *mmc, void *dst, lbaint_t blkcnt);  };
> > +
> > +static inline int mmc_hs400_prepare_ddr(struct mmc *mmc) {
> > +	return 0;
> > +}
> >  #endif
> >
> >  struct mmc_config {
> > --
> > 2.7.4



More information about the U-Boot mailing list