public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Jaehoon Chung <jh80.chung@samsung.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [RFC] mmc: Properly determine maximum supported bus width
Date: Thu, 01 Nov 2012 17:07:02 +0900	[thread overview]
Message-ID: <50922DA6.7050009@samsung.com> (raw)
In-Reply-To: <1351746158-19009-1-git-send-email-afleming@freescale.com>

Hi Andy,

It's working fine on my environment.

Tested-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

On 11/01/2012 02:02 PM, Andy Fleming wrote:
> At some point, a confusion arose about the use of the bit
> definitions in host_caps for bus widths, and the value
> in ext_csd. By coincidence, a simple shift could convert
> between one and the other:
> 
> MMC_MODE_1BIT = 0, EXT_CSD_BUS_WIDTH_1 = 0
> MMC_MODE_4BIT = 0x100, EXT_CSD_BUS_WIDTH_4 = 1
> MMC_MODE_8BIT = 0x200, EXT_CSD_BUS_WIDTH_8 = 2
> 
> However, as host_caps is a bitmask of supported things,
> there is not, in fact, a one-to-one correspondence. host_caps
> is capable of containing MODE_4BIT | MODE_8BIT, so nonsensical
> things were happening where we would try to set the bus width
> to 12.
> 
> The new code clarifies the very different namespaces:
> 
> host_caps/card_caps = bitmask (MMC_MODE_*)
> ext CSD fields are just an index (EXT_CSD_BUS_WIDTH_*)
> mmc->bus_width integer number of bits (1, 4, 8)
> 
> We create arrays to map between the namespaces, like in Linux.
> 
> Signed-off-by: Andy Fleming <afleming@freescale.com>
> ---
> 
> This is, I think, the approach we should use to identify the
> proper bus width for an mmc device. Please review and/or test.
> 
> 
>  drivers/mmc/mmc.c |   47 +++++++++++++++++++++++++++++++++++------------
>  1 file changed, 35 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 5fbf956..c379a74 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -867,7 +867,7 @@ void mmc_set_bus_width(struct mmc *mmc, uint width)
>  
>  int mmc_startup(struct mmc *mmc)
>  {
> -	int err, width;
> +	int err;
>  	uint mult, freq;
>  	u64 cmult, csize, capacity;
>  	struct mmc_cmd cmd;
> @@ -1086,21 +1086,44 @@ int mmc_startup(struct mmc *mmc)
>  		else
>  			mmc->tran_speed = 25000000;
>  	} else {
> -		width = ((mmc->host_caps & MMC_MODE_MASK_WIDTH_BITS) >>
> -			 MMC_MODE_WIDTH_BITS_SHIFT);
> -		for (; width >= 0; width--) {
> -			/* Set the card to use 4 bit*/
> +		int idx;
> +
> +		/* An array of possible bus widths in order of preference */
> +		static unsigned ext_csd_bits[] = {
> +			EXT_CSD_BUS_WIDTH_8,
> +			EXT_CSD_BUS_WIDTH_4,
> +			EXT_CSD_BUS_WIDTH_1,
> +		};
> +
> +		/* An array to map CSD bus widths to host cap bits */
> +		static unsigned ext_to_hostcaps[] = {
> +			[EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
> +			[EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
> +		};
> +
> +		/* An array to map chosen bus width to an integer */
> +		static unsigned widths[] = {
> +			8, 4, 1,
> +		};
> +
> +		for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
> +			unsigned int extw = ext_csd_bits[idx];
> +
> +			/*
> +			 * Check to make sure the controller supports
> +			 * this bus width, if it's more than 1
> +			 */
> +			if (extw != EXT_CSD_BUS_WIDTH_1 &&
> +					!(mmc->host_caps & ext_to_hostcaps[extw]))
> +				continue;
> +
>  			err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
> -					EXT_CSD_BUS_WIDTH, width);
> +					EXT_CSD_BUS_WIDTH, extw);
>  
>  			if (err)
>  				continue;
>  
> -			if (!width) {
> -				mmc_set_bus_width(mmc, 1);
> -				break;
> -			} else
> -				mmc_set_bus_width(mmc, 4 * width);
> +			mmc_set_bus_width(mmc, widths[idx]);
>  
>  			err = mmc_send_ext_csd(mmc, test_csd);
>  			if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
> @@ -1114,7 +1137,7 @@ int mmc_startup(struct mmc *mmc)
>  				 && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
>  					&test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
>  
> -				mmc->card_caps |= width;
> +				mmc->card_caps |= ext_to_hostcaps[extw];
>  				break;
>  			}
>  		}
> 

  reply	other threads:[~2012-11-01  8:07 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-01  5:02 [U-Boot] [RFC] mmc: Properly determine maximum supported bus width Andy Fleming
2012-11-01  8:07 ` Jaehoon Chung [this message]
2012-11-02 16:12 ` Stephen Warren
2012-11-26 23:27 ` Stephen Warren
2012-11-26 23:33   ` Fleming Andy-AFLEMING
2012-11-27 23:40     ` Stephen Warren
2012-11-27 23:44       ` Andy Fleming

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=50922DA6.7050009@samsung.com \
    --to=jh80.chung@samsung.com \
    --cc=u-boot@lists.denx.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