Hi Peng, > -----Original Message----- > From: Peng Fan <peng....@nxp.com> > Sent: Monday, July 20, 2020 9:33 AM > To: Y.b. Lu <yangbo...@nxp.com>; u-boot@lists.denx.de; Priyanka Jain > <priyanka.j...@nxp.com>; 'Jaehoon Chung' <jh80.ch...@samsung.com> > Cc: Y.b. Lu <yangbo...@nxp.com> > Subject: RE: [v2, 01/11] mmc: add a reinit() API > > > Subject: [v2, 01/11] mmc: add a reinit() API > > > > For DM_MMC, the controller re-initialization is needed to clear old > > configuration for mmc rescan. > > > > Signed-off-by: Yangbo Lu <yangbo...@nxp.com> > > --- > > Changes for v2: > > - None. > > --- > > drivers/mmc/mmc-uclass.c | 15 +++++++++++++++ > > drivers/mmc/mmc.c | 8 ++++++-- > > include/mmc.h | 10 ++++++++++ > > 3 files changed, 31 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index > > c5b7872..b9f0880 100644 > > --- a/drivers/mmc/mmc-uclass.c > > +++ b/drivers/mmc/mmc-uclass.c > > @@ -170,6 +170,21 @@ int mmc_deferred_probe(struct mmc *mmc) > > return dm_mmc_deferred_probe(mmc->dev); } > > > > +int dm_mmc_reinit(struct udevice *dev) > > +{ > > + struct dm_mmc_ops *ops = mmc_get_ops(dev); > > + > > + if (ops->reinit) > > + return ops->reinit(dev); > > + > > + return 0; > > +} > > + > > +int mmc_reinit(struct mmc *mmc) > > +{ > > + return dm_mmc_reinit(mmc->dev); > > +} > > + > > int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg) { > > int val; > > diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index > > 50f47d4..a53f93a 100644 > > --- a/drivers/mmc/mmc.c > > +++ b/drivers/mmc/mmc.c > > @@ -2813,13 +2813,17 @@ int mmc_get_op_cond(struct mmc *mmc) > > return err; > > > > #if CONFIG_IS_ENABLED(DM_MMC) > > - /* The device has already been probed ready for use */ > > + /* > > + * Re-initialization is needed to clear old configuration for > > + * mmc rescan. > > You mean cmd "mmc rescan" ?
Yes. The flag has_init is being used to skip the reinitialization if the card has been initialized once. Going through the mmc driver, the only place where we want to actually and completely reinitialize the SD card is "mmc rescan". For "mmc rescan", before sending CMD0 to reset card, the controller is still needed to be reset/re-initialized. Otherwise the controller may be still in previous status (registers setting) communicating with the card. > > > + */ > > + err = mmc_reinit(mmc); > > Probe could not provide what you need? You need a different settings? Probe is called only once. The controller still needs to be reset/re-initialized to clean all previous registers setting, before sending CMD0 for mmc rescan. For example, the eSDHC controller is now in 8-bit 200MHz eMMC HS400 mode (in tuning mode). When we want mmc rescan to completely reinitialize the card starting from CMD0, we needs to reset/re-initialize the controller to clean previous HS400 mode setting. > > Regards, > Peng. > > > #else > > /* made sure it's not NULL earlier */ > > err = mmc->cfg->ops->init(mmc); > > +#endif > > if (err) > > return err; > > -#endif > > mmc->ddr_mode = 0; > > > > retry: > > diff --git a/include/mmc.h b/include/mmc.h index 8256219..161b8bc > 100644 > > --- a/include/mmc.h > > +++ b/include/mmc.h > > @@ -422,6 +422,14 @@ struct dm_mmc_ops { > > */ > > int (*deferred_probe)(struct udevice *dev); > > /** > > + * reinit() - Re-initialization to clear old configuration for > > + * mmc rescan. > > + * > > + * @dev: Device to reinit > > + * @return 0 if Ok, -ve if error > > + */ > > + int (*reinit)(struct udevice *dev); > > + /** > > * send_cmd() - Send a command to the MMC device > > * > > * @dev: Device to receive the command > > @@ -518,6 +526,7 @@ int dm_mmc_execute_tuning(struct udevice *dev, > > uint opcode); int dm_mmc_wait_dat0(struct udevice *dev, int state, int > > timeout_us); int dm_mmc_host_power_cycle(struct udevice *dev); int > > dm_mmc_deferred_probe(struct udevice *dev); > > +int dm_mmc_reinit(struct udevice *dev); > > int dm_mmc_get_b_max(struct udevice *dev, void *dst, lbaint_t blkcnt); > > > > /* Transition functions for compatibility */ @@ -529,6 +538,7 @@ int > > mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us); int > > mmc_set_enhanced_strobe(struct mmc *mmc); 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); > > > > #else > > -- > > 2.7.4