[PATCH 1/2] mci: add eMMC DDR52 support

Ahmad Fatoum a.fatoum at pengutronix.de
Tue Apr 18 00:36:32 PDT 2023


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 at 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 |




More information about the barebox mailing list