From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: Marco Felsch <m.felsch@pengutronix.de>
Cc: barebox@lists.infradead.org
Subject: Re: [PATCH 1/2] mci: add eMMC DDR52 support
Date: Tue, 18 Apr 2023 09:36:32 +0200 [thread overview]
Message-ID: <8bdc6be0-497a-8442-4694-5024a797fd64@pengutronix.de> (raw)
In-Reply-To: <20230418072712.pijqhlrlcyrkzoiy@pengutronix.de>
Hello Marco,
On 18.04.23 09:27, Marco Felsch wrote:
> Hi Ahmad,
>
> On 23-04-17, Ahmad Fatoum wrote:
>> The maximum card frequency that can be configured by barebox currently
>> is 50MHz for SD and 52MHz for eMMC. Higher speed modes require runtime
>> voltage switching or tuning sequences, which are not yet implemented.
>>
>> Only exception is eMMC's DDR52: This mode was first introduced with
>> MMC 4.4 and can be used even at 3.3V.
>
> Nice :)
>
>> This commit adds DDR52 support to the core. This introduces no functional
>> change, because host controllers must opt-in by setting the appropriate
>> host capabilities.
>>
>> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>> ---
>> drivers/mci/mci-core.c | 54 +++++++++++++++++++++++++++++++++++-------
>> include/mci.h | 19 +++++++++++++++
>> 2 files changed, 64 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
>> index f647cae8203b..86f468edfea6 100644
>> --- a/drivers/mci/mci-core.c
>> +++ b/drivers/mci/mci-core.c
>> @@ -135,6 +135,9 @@ static int mci_set_blocklen(struct mci *mci, unsigned len)
>> {
>> struct mci_cmd cmd;
>>
>> + if (mci->host->timing == MMC_TIMING_MMC_DDR52)
>> + return 0;
>> +
>> mci_setup_cmd(&cmd, MMC_CMD_SET_BLOCKLEN, len, MMC_RSP_R1);
>> return mci_send_cmd(mci, &cmd, NULL);
>> }
>> @@ -649,11 +652,15 @@ static int mmc_change_freq(struct mci *mci)
>> return 0;
>> }
>>
>> - /* High Speed is set, there are two types: 52MHz and 26MHz */
>> - if (cardtype & EXT_CSD_CARD_TYPE_52)
>> - mci->card_caps |= MMC_CAP_MMC_HIGHSPEED_52MHZ | MMC_CAP_MMC_HIGHSPEED;
>> - else
>> - mci->card_caps |= MMC_CAP_MMC_HIGHSPEED;
>> + mci->card_caps |= MMC_CAP_MMC_HIGHSPEED;
>> +
>> + /* High Speed is set, there are three types: 26MHz, 52MHz, 52MHz DDR */
>> + if (cardtype & EXT_CSD_CARD_TYPE_52) {
>> + mci->card_caps |= MMC_CAP_MMC_HIGHSPEED_52MHZ;
>> +
>> + if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
>> + mci->card_caps |= MMC_CAP_MMC_3_3V_DDR | MMC_CAP_MMC_1_8V_DDR;
>> + }
>>
>> if (IS_ENABLED(CONFIG_MCI_MMC_BOOT_PARTITIONS) &&
>> mci->ext_csd[EXT_CSD_REV] >= 3 && mci->ext_csd[EXT_CSD_BOOT_SIZE_MULT]) {
>> @@ -1170,15 +1177,20 @@ static int mci_startup_sd(struct mci *mci)
>> static int mci_startup_mmc(struct mci *mci)
>> {
>> struct mci_host *host = mci->host;
>> + enum mci_timing timing_orig;
>> int err;
>> int idx = 0;
>> static unsigned ext_csd_bits[] = {
>> EXT_CSD_BUS_WIDTH_4,
>> EXT_CSD_BUS_WIDTH_8,
>> + EXT_CSD_DDR_BUS_WIDTH_4,
>> + EXT_CSD_DDR_BUS_WIDTH_8,
>> };
>> static unsigned bus_widths[] = {
>> MMC_BUS_WIDTH_4,
>> MMC_BUS_WIDTH_8,
>> + MMC_BUS_WIDTH_4,
>> + MMC_BUS_WIDTH_8,
>
> This is duplicated or should it be MMC_DDR_BUS_WIDTH_4/8?
The trial sequence I had in mind originally was:
DDR 8-bit -> DDR 4-bit -> SDR 8-bit -> SDR 4-bit
That's how U-Boot does it. I compared with Linux and there we have:
SDR 8-bit -> SDR 4-bit and then depending on the result, either
DDR 8-bit or DDR 4-bit
Given that DDR is not a 100% improvement in my testing, I should
rather do it like Linux does and prefer SDR 8-bit over DDR 4-bit.
I will do this for v2.
This also fixes a bug with the code: If host doesn't support 8-bit
MMC, we would still not test for 8-bit SDR, but would for 8-bit DDR.
>> @@ -1661,12 +1694,15 @@ static const char *mci_timing_tostr(unsigned timing)
>>
>> static void mci_print_caps(unsigned caps)
>> {
>> - printf(" capabilities: %s%s%s%s%s\n",
>> + printf(" capabilities: %s%s%s%s%s%s%s%s\n",
>> caps & MMC_CAP_4_BIT_DATA ? "4bit " : "",
>> caps & MMC_CAP_8_BIT_DATA ? "8bit " : "",
>> caps & MMC_CAP_SD_HIGHSPEED ? "sd-hs " : "",
>> caps & MMC_CAP_MMC_HIGHSPEED ? "mmc-hs " : "",
>> - caps & MMC_CAP_MMC_HIGHSPEED_52MHZ ? "mmc-52MHz " : "");
>> + caps & MMC_CAP_MMC_HIGHSPEED_52MHZ ? "mmc-52MHz " : "",
>> + caps & MMC_CAP_MMC_3_3V_DDR ? "ddr-3.3v " : "",
>> + caps & MMC_CAP_MMC_1_8V_DDR ? "ddr-1.8v " : "",
>> + caps & MMC_CAP_MMC_1_2V_DDR ? "ddr-1.2v " : "");
>
> At the moment we only report what barebox does support, ddr-1.8v and
> ddr-1.2v isn't supported. Do we really want to report this?
DDR 1.8V on eMMC is not dynamically selected, but 1.2v is. So this
series works for both 3.3v and 1.8v. I don't see a problem with reporting
1.2v support for cards. No host will set this as long we don't have
voltage switching.
Cheers,
Ahmad
>
> Regards,
> Marco
>
>> }
>>
>> /**
>> diff --git a/include/mci.h b/include/mci.h
>> index d356f071f7f2..88712c35492e 100644
>> --- a/include/mci.h
>> +++ b/include/mci.h
>> @@ -51,6 +51,11 @@
>> #define MMC_CAP_SD_HIGHSPEED (1 << 3)
>> #define MMC_CAP_MMC_HIGHSPEED (1 << 4)
>> #define MMC_CAP_MMC_HIGHSPEED_52MHZ (1 << 5)
>> +#define MMC_CAP_MMC_3_3V_DDR (1 << 7) /* Host supports eMMC DDR 3.3V */
>> +#define MMC_CAP_MMC_1_8V_DDR (1 << 8) /* Host supports eMMC DDR 1.8V */
>> +#define MMC_CAP_MMC_1_2V_DDR (1 << 9) /* Host supports eMMC DDR 1.2V */
>> +#define MMC_CAP_DDR (MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR | \
>> + MMC_CAP_1_2V_DDR)
>> /* Mask of all caps for bus width */
>> #define MMC_CAP_BIT_DATA_MASK (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)
>>
>> @@ -308,6 +313,7 @@
>> #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
>> #define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
>> #define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
>> +#define EXT_CSD_DDR_FLAG BIT(2) /* Flag for DDR mode */
>>
>> #define R1_ILLEGAL_COMMAND (1 << 22)
>> #define R1_STATUS(x) (x & 0xFFF9A000)
>> @@ -410,6 +416,19 @@ enum mci_timing {
>> MMC_TIMING_MMC_HS400 = 8,
>> };
>>
>> +static inline bool mci_timing_is_ddr(enum mci_timing timing)
>> +{
>> + switch (timing) {
>> + case MMC_TIMING_UHS_DDR50:
>> + case MMC_TIMING_MMC_HS200:
>> + case MMC_TIMING_MMC_DDR52:
>> + case MMC_TIMING_MMC_HS400:
>> + return true;
>> + default:
>> + return false;
>> + }
>> +}
>> +
>> struct mci_ios {
>> unsigned int clock; /* clock rate */
>>
>> --
>> 2.39.2
>>
>>
>>
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
prev parent reply other threads:[~2023-04-18 7:37 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-17 16:42 Ahmad Fatoum
2023-04-17 16:42 ` [PATCH 2/2] mci: imx-esdhc: add uSDHC eMMC DDR52 supprot Ahmad Fatoum
2023-04-18 7:32 ` Marco Felsch
2023-04-18 7:27 ` [PATCH 1/2] mci: add eMMC DDR52 support Marco Felsch
2023-04-18 7:36 ` Ahmad Fatoum [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8bdc6be0-497a-8442-4694-5024a797fd64@pengutronix.de \
--to=a.fatoum@pengutronix.de \
--cc=barebox@lists.infradead.org \
--cc=m.felsch@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox