[U-Boot] [PATCH V4 1/2] mmc: add HS400 support
Tom Rini
trini at konsulko.com
Wed Aug 29 11:21:26 UTC 2018
On Wed, Aug 29, 2018 at 12:35:05PM +0200, Marek Vasut wrote:
> On 08/29/2018 07:32 AM, Peng Fan wrote:
> > Hi,
>
> Hi,
>
> > Would anyone pick up this patchset? Tom, I delegated the patchset to you, would you mind pick it up?
>
> I've been nagging Tom about this for a while , he said he will pick it
> for next release, but having it in this one would be IMO fine, since it
> doesn't interfere with anything and it's been posted way before the RC
> cycle started.
Yes, I still intend to pick it up after v2018.09. Thanks for the
reminder!
>
> > Thanks,
> > Peng.
> >
> > -----Original Message-----
> > From: Peng Fan
> > Sent: 2018年8月10日 14:08
> > To: jh80.chung at samsung.com; sbabic at denx.de
> > Cc: u-boot at lists.denx.de; dl-linux-imx <linux-imx at nxp.com>; Peng Fan <peng.fan at nxp.com>; Jean-Jacques Hiblot <jjhiblot at ti.com>; Kishon Vijay Abraham I <kishon at ti.com>; Faiz Abbas <faiz_abbas at ti.com>; Marek Vasut <marex at denx.de>
> > Subject: [PATCH V4 1/2] mmc: add HS400 support
> >
> > Add HS400 support.
> > Selecting HS400 needs first select HS200 according to spec, so use a dedicated function for HS400.
> > Add HS400 related macros.
> > Remove the restriction of only using the low 6 bits of EXT_CSD_CARD_TYPE, using all the 8 bits.
> >
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > Cc: Jaehoon Chung <jh80.chung at samsung.com>
> > Cc: Jean-Jacques Hiblot <jjhiblot at ti.com>
> > Cc: Stefano Babic <sbabic at denx.de>
> > Cc: Kishon Vijay Abraham I <kishon at ti.com>
> > Cc: Faiz Abbas <faiz_abbas at ti.com>
> > Cc: Marek Vasut <marex at denx.de>
> > ---
> >
> > V4:
> > Add SPL_MMC_HS400_SUPPORT Kconfig entry typo fix, HS199->HS200 in commit log.
> >
> > V3:
> > Simplify code
> > add error msg
> >
> > V2:
> > remove 4bits support from HS400, as HS400 does not support 4bits per spec.
> >
> > drivers/mmc/Kconfig | 13 +++++
> > drivers/mmc/mmc.c | 137 +++++++++++++++++++++++++++++++++++++++++-----------
> > include/mmc.h | 11 +++++
> > 3 files changed, 134 insertions(+), 27 deletions(-)
> >
> > diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 377b1c4b3b..1616022b91 100644
> > --- a/drivers/mmc/Kconfig
> > +++ b/drivers/mmc/Kconfig
> > @@ -111,6 +111,19 @@ config SPL_MMC_UHS_SUPPORT
> > cards. The IO voltage must be switchable from 3.3v to 1.8v. The bus
> > frequency can go up to 208MHz (SDR104)
> >
> > +config MMC_HS400_SUPPORT
> > + bool "enable HS400 support"
> > + select MMC_HS200_SUPPORT
> > + help
> > + The HS400 mode is support by some eMMC. The bus frequency is up to
> > + 200MHz. This mode requires tuning the IO.
> > +
> > +config SPL_MMC_HS400_SUPPORT
> > + bool "enable HS400 support in SPL"
> > + help
> > + The HS400 mode is support by some eMMC. The bus frequency is up to
> > + 200MHz. This mode requires tuning the IO.
> > +
> > config MMC_HS200_SUPPORT
> > bool "enable HS200 support"
> > help
> > diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index ad429f49c9..585951cd78 100644
> > --- a/drivers/mmc/mmc.c
> > +++ b/drivers/mmc/mmc.c
> > @@ -147,6 +147,7 @@ const char *mmc_mode_name(enum bus_mode mode)
> > [MMC_HS_52] = "MMC High Speed (52MHz)",
> > [MMC_DDR_52] = "MMC DDR52 (52MHz)",
> > [MMC_HS_200] = "HS200 (200MHz)",
> > + [MMC_HS_400] = "HS400 (200MHz)",
> > };
> >
> > if (mode >= MMC_MODES_END)
> > @@ -171,6 +172,7 @@ static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
> > [UHS_DDR50] = 50000000,
> > [UHS_SDR104] = 208000000,
> > [MMC_HS_200] = 200000000,
> > + [MMC_HS_400] = 200000000,
> > };
> >
> > if (mode == MMC_LEGACY)
> > @@ -769,6 +771,11 @@ static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode)
> > case MMC_HS_200:
> > speed_bits = EXT_CSD_TIMING_HS200;
> > break;
> > +#endif
> > +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> > + case MMC_HS_400:
> > + speed_bits = EXT_CSD_TIMING_HS400;
> > + break;
> > #endif
> > case MMC_LEGACY:
> > speed_bits = EXT_CSD_TIMING_LEGACY;
> > @@ -816,7 +823,7 @@ static int mmc_get_capabilities(struct mmc *mmc)
> >
> > mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
> >
> > - cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0x3f;
> > + cardtype = ext_csd[EXT_CSD_CARD_TYPE];
> > mmc->cardtype = cardtype;
> >
> > #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
> > @@ -824,6 +831,12 @@ static int mmc_get_capabilities(struct mmc *mmc)
> > EXT_CSD_CARD_TYPE_HS200_1_8V)) {
> > mmc->card_caps |= MMC_MODE_HS200;
> > }
> > +#endif
> > +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> > + if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
> > + EXT_CSD_CARD_TYPE_HS400_1_8V)) {
> > + mmc->card_caps |= MMC_MODE_HS400;
> > + }
> > #endif
> > if (cardtype & EXT_CSD_CARD_TYPE_52) {
> > if (cardtype & EXT_CSD_CARD_TYPE_DDR_52) @@ -1734,10 +1747,13 @@ static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
> > u32 card_mask = 0;
> >
> > switch (mode) {
> > + case MMC_HS_400:
> > case MMC_HS_200:
> > - if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_8V)
> > + if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_8V |
> > + EXT_CSD_CARD_TYPE_HS400_1_8V))
> > card_mask |= MMC_SIGNAL_VOLTAGE_180;
> > - if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_2V)
> > + if (mmc->cardtype & (EXT_CSD_CARD_TYPE_HS200_1_2V |
> > + EXT_CSD_CARD_TYPE_HS400_1_2V))
> > card_mask |= MMC_SIGNAL_VOLTAGE_120;
> > break;
> > case MMC_DDR_52:
> > @@ -1773,6 +1789,13 @@ static inline int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode, #endif
> >
> > static const struct mode_width_tuning mmc_modes_by_pref[] = {
> > +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> > + {
> > + .mode = MMC_HS_400,
> > + .widths = MMC_MODE_8BIT,
> > + .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
> > + },
> > +#endif
> > #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
> > {
> > .mode = MMC_HS_200,
> > @@ -1816,6 +1839,54 @@ static const struct ext_csd_bus_width {
> > {MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1}, };
> >
> > +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> > +static int mmc_select_hs400(struct mmc *mmc) {
> > + int err;
> > +
> > + /* Set timing to HS200 for tuning */
> > + err = mmc_set_card_speed(mmc, MMC_HS_200);
> > + if (err)
> > + return err;
> > +
> > + /* configure the bus mode (host) */
> > + mmc_select_mode(mmc, MMC_HS_200);
> > + mmc_set_clock(mmc, mmc->tran_speed, false);
> > +
> > + /* execute tuning if needed */
> > + err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
> > + if (err) {
> > + debug("tuning failed\n");
> > + return err;
> > + }
> > +
> > + /* Set back to HS */
> > + mmc_set_card_speed(mmc, MMC_HS);
> > + mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
> > +
> > + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
> > + EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
> > + if (err)
> > + return err;
> > +
> > + err = mmc_set_card_speed(mmc, MMC_HS_400);
> > + if (err)
> > + return err;
> > +
> > + mmc_select_mode(mmc, MMC_HS_400);
> > + err = mmc_set_clock(mmc, mmc->tran_speed, false);
> > + if (err)
> > + return err;
> > +
> > + return 0;
> > +}
> > +#else
> > +static int mmc_select_hs400(struct mmc *mmc) {
> > + return -ENOTSUPP;
> > +}
> > +#endif
> > +
> > #define for_each_supported_width(caps, ddr, ecbv) \
> > for (ecbv = ext_csd_bus_width;\
> > ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\ @@ -1869,37 +1940,49 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
> > goto error;
> > mmc_set_bus_width(mmc, bus_width(ecbw->cap));
> >
> > - /* configure the bus speed (card) */
> > - err = mmc_set_card_speed(mmc, mwt->mode);
> > - if (err)
> > - goto error;
> > -
> > - /*
> > - * configure the bus width AND the ddr mode (card)
> > - * The host side will be taken care of in the next step
> > - */
> > - if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
> > - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
> > - EXT_CSD_BUS_WIDTH,
> > - ecbw->ext_csd_bits);
> > + if (mwt->mode == MMC_HS_400) {
> > + err = mmc_select_hs400(mmc);
> > + if (err) {
> > + printf("Select HS400 failed %d\n", err);
> > + goto error;
> > + }
> > + } else {
> > + /* configure the bus speed (card) */
> > + err = mmc_set_card_speed(mmc, mwt->mode);
> > if (err)
> > goto error;
> > - }
> >
> > - /* configure the bus mode (host) */
> > - mmc_select_mode(mmc, mwt->mode);
> > - mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
> > + /*
> > + * configure the bus width AND the ddr mode
> > + * (card). The host side will be taken care
> > + * of in the next step
> > + */
> > + if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
> > + err = mmc_switch(mmc,
> > + EXT_CSD_CMD_SET_NORMAL,
> > + EXT_CSD_BUS_WIDTH,
> > + ecbw->ext_csd_bits);
> > + if (err)
> > + goto error;
> > + }
> > +
> > + /* configure the bus mode (host) */
> > + mmc_select_mode(mmc, mwt->mode);
> > + mmc_set_clock(mmc, mmc->tran_speed,
> > + MMC_CLK_ENABLE);
> > #ifdef MMC_SUPPORTS_TUNING
> >
> > - /* execute tuning if needed */
> > - if (mwt->tuning) {
> > - err = mmc_execute_tuning(mmc, mwt->tuning);
> > - if (err) {
> > - pr_debug("tuning failed\n");
> > - goto error;
> > + /* execute tuning if needed */
> > + if (mwt->tuning) {
> > + err = mmc_execute_tuning(mmc,
> > + mwt->tuning);
> > + if (err) {
> > + pr_debug("tuning failed\n");
> > + goto error;
> > + }
> > }
> > - }
> > #endif
> > + }
> >
> > /* do a transfer to check the configuration */
> > err = mmc_read_and_compare_ext_csd(mmc);
> > diff --git a/include/mmc.h b/include/mmc.h index df4255b828..9b9cbedadc 100644
> > --- a/include/mmc.h
> > +++ b/include/mmc.h
> > @@ -64,6 +64,7 @@
> > #define MMC_MODE_HS_52MHz MMC_CAP(MMC_HS_52)
> > #define MMC_MODE_DDR_52MHz MMC_CAP(MMC_DDR_52)
> > #define MMC_MODE_HS200 MMC_CAP(MMC_HS_200)
> > +#define MMC_MODE_HS400 MMC_CAP(MMC_HS_400)
> >
> > #define MMC_MODE_8BIT BIT(30)
> > #define MMC_MODE_4BIT BIT(29)
> > @@ -248,6 +249,10 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
> > /* SDR mode @1.2V I/O */
> > #define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
> > EXT_CSD_CARD_TYPE_HS200_1_2V)
> > +#define EXT_CSD_CARD_TYPE_HS400_1_8V BIT(6)
> > +#define EXT_CSD_CARD_TYPE_HS400_1_2V BIT(7)
> > +#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
> > + EXT_CSD_CARD_TYPE_HS400_1_2V)
> >
> > #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
> > #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
> > @@ -259,6 +264,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
> > #define EXT_CSD_TIMING_LEGACY 0 /* no high speed */
> > #define EXT_CSD_TIMING_HS 1 /* HS */
> > #define EXT_CSD_TIMING_HS200 2 /* HS200 */
> > +#define EXT_CSD_TIMING_HS400 3 /* HS400 */
> >
> > #define EXT_CSD_BOOT_ACK_ENABLE (1 << 6)
> > #define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3)
> > @@ -519,6 +525,7 @@ enum bus_mode {
> > UHS_DDR50,
> > UHS_SDR104,
> > MMC_HS_200,
> > + MMC_HS_400,
> > MMC_MODES_END
> > };
> >
> > @@ -532,6 +539,10 @@ static inline bool mmc_is_mode_ddr(enum bus_mode mode) #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
> > else if (mode == UHS_DDR50)
> > return true;
> > +#endif
> > +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
> > + else if (mode == MMC_HS_400)
> > + return true;
> > #endif
> > else
> > return false;
> > --
> > 2.14.1
> >
>
>
> --
> Best regards,
> Marek Vasut
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20180829/dbfda43d/attachment.sig>
More information about the U-Boot
mailing list