RE: [PATCH v2 07/12] mmc: sd: set current limit for uhs cards

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Philip,


> -----Original Message-----
> From: Philip Rakity [mailto:prakity@xxxxxxxxxxx]
> Sent: Wednesday, March 16, 2011 9:01 PM
> To: Nath, Arindam
> Cc: cjb@xxxxxxxxxx; zhangfei.gao@xxxxxxxxx; subhashj@xxxxxxxxxxxxxx;
> linux-mmc@xxxxxxxxxxxxxxx; Su, Henry; Lu, Aaron; anath.amd@xxxxxxxxx
> Subject: Re: [PATCH v2 07/12] mmc: sd: set current limit for uhs cards
> 
> 
> Arindam,
> 
> Thanks,
> 
> There are a few other functions in the same file that should also be
> changed for the same reason.

I hope you mean by setting default bus speed mode and driver type for the card. If so, I will take care of them.

Thanks,
Arindam

> 
> Philip
> 
> On Mar 16, 2011, at 8:24 AM, Nath, Arindam wrote:
> 
> > Hi Philip,
> >
> >
> >> -----Original Message-----
> >> From: Philip Rakity [mailto:prakity@xxxxxxxxxxx]
> >> Sent: Wednesday, March 16, 2011 8:48 PM
> >> To: Nath, Arindam
> >> Cc: cjb@xxxxxxxxxx; zhangfei.gao@xxxxxxxxx; subhashj@xxxxxxxxxxxxxx;
> >> linux-mmc@xxxxxxxxxxxxxxx; Su, Henry; Lu, Aaron; anath.amd@xxxxxxxxx
> >> Subject: Re: [PATCH v2 07/12] mmc: sd: set current limit for uhs
> cards
> >>
> >>
> >> On Mar 16, 2011, at 8:00 AM, Nath, Arindam wrote:
> >>
> >>> Hi Philip,
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Philip Rakity [mailto:prakity@xxxxxxxxxxx]
> >>>> Sent: Wednesday, March 16, 2011 8:22 PM
> >>>> To: Nath, Arindam
> >>>> Cc: cjb@xxxxxxxxxx; zhangfei.gao@xxxxxxxxx;
> subhashj@xxxxxxxxxxxxxx;
> >>>> linux-mmc@xxxxxxxxxxxxxxx; Su, Henry; Lu, Aaron;
> anath.amd@xxxxxxxxx
> >>>> Subject: Re: [PATCH v2 07/12] mmc: sd: set current limit for uhs
> >> cards
> >>>>
> >>>>
> >>>> On Mar 16, 2011, at 7:32 AM, Nath, Arindam wrote:
> >>>>
> >>>>> Hi Philip,
> >>>>>
> >>>>>
> >>>>>> -----Original Message-----
> >>>>>> From: Philip Rakity [mailto:prakity@xxxxxxxxxxx]
> >>>>>> Sent: Wednesday, March 16, 2011 7:56 PM
> >>>>>> To: Nath, Arindam
> >>>>>> Cc: cjb@xxxxxxxxxx; zhangfei.gao@xxxxxxxxx;
> >> subhashj@xxxxxxxxxxxxxx;
> >>>>>> linux-mmc@xxxxxxxxxxxxxxx; Su, Henry; Lu, Aaron;
> >> anath.amd@xxxxxxxxx
> >>>>>> Subject: Re: [PATCH v2 07/12] mmc: sd: set current limit for uhs
> >>>> cards
> >>>>>>
> >>>>>>
> >>>>>> On Mar 4, 2011, at 3:32 AM, Arindam Nath wrote:
> >>>>>>
> >>>>>>> We decide on the current limit to be set for the card based on
> >> the
> >>>>>>> Capability of Host Controller to provide current at 1.8V
> >>>> signalling,
> >>>>>>> and the maximum current limit of the card as indicated by CMD6
> >>>>>>> mode 0. We then set the current limit for the card using CMD6
> >> mode
> >>>> 1.
> >>>>>>>
> >>>>>>> Signed-off-by: Arindam Nath <arindam.nath@xxxxxxx>
> >>>>>>> ---
> >>>>>>> drivers/mmc/core/sd.c    |   45
> >>>>>> +++++++++++++++++++++++++++++++++++++++++++++
> >>>>>>> drivers/mmc/host/sdhci.c |   24 ++++++++++++++++++++++++
> >>>>>>> include/linux/mmc/card.h |    9 +++++++++
> >>>>>>> include/linux/mmc/host.h |    1 +
> >>>>>>> 4 files changed, 79 insertions(+), 0 deletions(-)
> >>>>>>>
> >>>>>>> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
> >>>>>>> index ec0d8e6..df98a2c 100644
> >>>>>>> --- a/drivers/mmc/core/sd.c
> >>>>>>> +++ b/drivers/mmc/core/sd.c
> >>>>>>> @@ -550,6 +550,46 @@ static int sd_set_bus_speed_mode(struct
> >>>> mmc_card
> >>>>>> *card, u8 *status)
> >>>>>>> 	return 0;
> >>>>>>> }
> >>>>>>>
> >>>>>>> +static int sd_set_current_limit(struct mmc_card *card, u8
> >> *status)
> >>>>>>> +{
> >>>>>>> +	struct mmc_host *host = card->host;
> >>>>>>> +	int mmc_host_max_current_180, current_limit;
> >>>>>>> +	int err;
> >>>>>>> +
> >>>>>>> +	/* sanity check */
> >>>>>>> +	if (!host->ops->get_max_current_180)
> >>>>>>> +		return 0;
> >>>>>>
> >>>>>> a better name would be get_max_current rather than
> >>>> get_max_current_180
> >>>>>
> >>>>> The Max Current Capabilities register reports maximum currents
> for
> >>>> 1.8V, 3.0V and 3.3V. Since we are only interested in the maximum
> >>>> current at 1.8V, so I have added *_180 to the variable names to
> make
> >> it
> >>>> explicit.
> >>>>
> >>>> understand but that is the usage now and if we need to extend the
> >> code
> >>>> the name becomes misleading.
> >>>
> >>> Okay. I will remove *_180 in next version.
> >>>
> >>>>>
> >>>>>>
> >>>>>> do you want a test for get_max_current_180 < 400 ? and return 0
> >>>> have
> >>>>>> it do the switch
> >>>>>> by setting the value ?
> >>>>>
> >>>>> As mentioned in the Physical Layer spec v3.01, <400mA falls under
> >> the
> >>>> default current limit, so we don't need to set it in case any or
> all
> >> of
> >>>> the above conditions fail.
> >>>>
> >>>> if future cards have memory or power is not removed they will they
> >>>> retain the old setting ?  if so better to explicitly initialize.
> >>>
> >>> Can you please elaborate this a little further?
> >>
> >> Power to the sd slot is supplied via a regulator.  This is turned on
> at
> >> power on.
> >> sometime in the future a reboot is done.  power is NOT removed.  The
> >> device does not reset
> >> into the default state.   Have seen this on some boards.
> >
> > Thanks for the explanation. I will modify code to set the default
> current limit for the card.
> >
> > Regards,
> > Arindam
> >
> >>
> >>>
> >>> Thanks,
> >>> Arindam
> >>>
> >>>>
> >>>>>
> >>>>> Thanks,
> >>>>> Arindam
> >>>>>
> >>>>>>> +
> >>>>>>> +	/* Maximum current supported by host at 1.8V */
> >>>>>>> +	mmc_host_max_current_180 = host->ops-
> >>> get_max_current_180(host);
> >>>>>>> +
> >>>>>>> +	if (mmc_host_max_current_180 >= 800) {
> >>>>>>> +		if (card->sw_caps.uhs_curr_limit &
> >> SD_MAX_CURRENT_800)
> >>>>>>> +			current_limit = SD_SET_CURRENT_LIMIT_800;
> >>>>>>> +		else if (card->sw_caps.uhs_curr_limit &
> >> SD_MAX_CURRENT_600)
> >>>>>>> +			current_limit = SD_SET_CURRENT_LIMIT_600;
> >>>>>>> +		else if (card->sw_caps.uhs_curr_limit &
> >> SD_MAX_CURRENT_400)
> >>>>>>> +			current_limit = SD_SET_CURRENT_LIMIT_400;
> >>>>>>> +	} else if (mmc_host_max_current_180 >= 600) {
> >>>>>>> +		if (card->sw_caps.uhs_curr_limit &
> >> SD_MAX_CURRENT_600)
> >>>>>>> +			current_limit = SD_SET_CURRENT_LIMIT_600;
> >>>>>>> +		else if (card->sw_caps.uhs_curr_limit &
> >> SD_MAX_CURRENT_400)
> >>>>>>> +			current_limit = SD_SET_CURRENT_LIMIT_400;
> >>>>>>> +	} else if (mmc_host_max_current_180 >= 400)
> >>>>>>> +		if (card->sw_caps.uhs_curr_limit &
> >> SD_MAX_CURRENT_400)
> >>>>>>> +			current_limit = SD_SET_CURRENT_LIMIT_400;
> >>>>>>
> >>>>>> or
> >>>>>>      else
> >>>>>>             current_limit = SD_SET_CURRENT_LIMIT_200;
> >>>>>>> +
> >>>>>>> +	err = mmc_sd_switch(card, 1, 3, current_limit, status);
> >>>>>>> +	if (err)
> >>>>>>> +		return err;
> >>>>>>> +
> >>>>>>> +	if (((status[15] >> 4) & 0x0F) != current_limit)
> >>>>>>> +		printk(KERN_WARNING "%s: Problem setting current
> >> limit!\n",
> >>>>>>> +			mmc_hostname(card->host));
> >>>>>>> +
> >>>>>>> +	return 0;
> >>>>>>> +}
> >>>>>>> +
> >>>>>>> /*
> >>>>>>> * UHS-I specific initialization procedure
> >>>>>>> */
> >>>>>>> @@ -590,6 +630,11 @@ static int mmc_sd_init_uhs_card(struct
> >>>> mmc_card
> >>>>>> *card)
> >>>>>>>
> >>>>>>> 	/* Set bus speed mode of the card */
> >>>>>>> 	err = sd_set_bus_speed_mode(card, status);
> >>>>>>> +	if (err)
> >>>>>>> +		goto out;
> >>>>>>> +
> >>>>>>> +	/* Set current limit for the card */
> >>>>>>> +	err = sd_set_current_limit(card, status);
> >>>>>>>
> >>>>>>> out:
> >>>>>>> 	kfree(status);
> >>>>>>> diff --git a/drivers/mmc/host/sdhci.c
> b/drivers/mmc/host/sdhci.c
> >>>>>>> index f127fa2..245cc39 100644
> >>>>>>> --- a/drivers/mmc/host/sdhci.c
> >>>>>>> +++ b/drivers/mmc/host/sdhci.c
> >>>>>>> @@ -1462,12 +1462,36 @@ static int
> >>>>>> sdhci_start_signal_voltage_switch(struct mmc_host *mmc)
> >>>>>>> 	return -EAGAIN;
> >>>>>>> }
> >>>>>>>
> >>>>>>
> >>>>>> better name is sdhci_get_max_current
> >>>>>>
> >>>>>>> +static int sdhci_get_max_current_180(struct mmc_host *mmc)
> >>>>>>> +{
> >>>>>>> +	struct sdhci_host *host;
> >>>>>>> +	u32 max_current_caps;
> >>>>>>> +	unsigned long flags;
> >>>>>>> +	int max_current_180;
> >>>>>>> +
> >>>>>>> +	host = mmc_priv(mmc);
> >>>>>>> +
> >>>>>>> +	spin_lock_irqsave(&host->lock, flags);
> >>>>>>> +
> >>>>>>> +	max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT);
> >>>>>>> +
> >>>>>>> +	spin_unlock_irqrestore(&host->lock, flags);
> >>>>>>> +
> >>>>>>> +	/* Maximum current is 4 times the register value for 1.8V
> >> */
> >>>>>>> +	max_current_180 = ((max_current_caps &
> >>>>>> SDHCI_MAX_CURRENT_180_MASK) >>
> >>>>>>> +			   SDHCI_MAX_CURRENT_180_SHIFT) *
> >>>>>>> +			   SDHCI_MAX_CURRENT_MULTIPLIER;
> >>>>>>
> >>>>>> SDHCI_MAX_CURRENT_SHIFT is better name.
> >>>>>>
> >>>>>>> +
> >>>>>>> +	return max_current_180;
> >>>>>>> +}
> >>>>>>> +
> >>>>>>> static const struct mmc_host_ops sdhci_ops = {
> >>>>>>> 	.request	= sdhci_request,
> >>>>>>> 	.set_ios	= sdhci_set_ios,
> >>>>>>> 	.get_ro		= sdhci_get_ro,
> >>>>>>> 	.enable_sdio_irq = sdhci_enable_sdio_irq,
> >>>>>>> 	.start_signal_voltage_switch	=
> >>>>>> sdhci_start_signal_voltage_switch,
> >>>>>>> +	.get_max_current_180		= sdhci_get_max_current_180,
> >>>>>>
> >>>>>> .get_max_current = sdhci_get_max_current;
> >>>>>>> };
> >>>>>>>
> >>>>>>>
> >>>>>>
> >>>>
> >>
> /**********************************************************************
> >>>>>> *******\
> >>>>>>> diff --git a/include/linux/mmc/card.h
> b/include/linux/mmc/card.h
> >>>>>>> index 0b24c41..a6811ae 100644
> >>>>>>> --- a/include/linux/mmc/card.h
> >>>>>>> +++ b/include/linux/mmc/card.h
> >>>>>>> @@ -98,6 +98,15 @@ struct sd_switch_caps {
> >>>>>>> #define SD_DRIVER_TYPE_C	0x04
> >>>>>>> #define SD_DRIVER_TYPE_D	0x08
> >>>>>>> 	unsigned int		uhs_curr_limit;
> >>>>>>> +#define SD_SET_CURRENT_LIMIT_200	0
> >>>>>>> +#define SD_SET_CURRENT_LIMIT_400	1
> >>>>>>> +#define SD_SET_CURRENT_LIMIT_600	2
> >>>>>>> +#define SD_SET_CURRENT_LIMIT_800	3
> >>>>>>> +
> >>>>>>> +#define SD_MAX_CURRENT_200	(1 << SD_SET_CURRENT_LIMIT_200)
> >>>>>>> +#define SD_MAX_CURRENT_400	(1 << SD_SET_CURRENT_LIMIT_400)
> >>>>>>> +#define SD_MAX_CURRENT_600	(1 << SD_SET_CURRENT_LIMIT_600)
> >>>>>>> +#define SD_MAX_CURRENT_800	(1 << SD_SET_CURRENT_LIMIT_800)
> >>>>>>> };
> >>>>>>>
> >>>>>>> struct sdio_cccr {
> >>>>>>> diff --git a/include/linux/mmc/host.h
> b/include/linux/mmc/host.h
> >>>>>>> index 4dfff6d..e84cd05 100644
> >>>>>>> --- a/include/linux/mmc/host.h
> >>>>>>> +++ b/include/linux/mmc/host.h
> >>>>>>> @@ -128,6 +128,7 @@ struct mmc_host_ops {
> >>>>>>> 	void	(*init_card)(struct mmc_host *host, struct mmc_card
> >> *card);
> >>>>>>>
> >>>>>>> 	int	(*start_signal_voltage_switch)(struct mmc_host
> >> *host);
> >>>>>>> +	int	(*get_max_current_180)(struct mmc_host *mmc);
> >>>>>>> };
> >>>>>>>
> >>>>>>> struct mmc_card;
> >>>>>>> --
> >>>>>>> 1.7.1
> >>>>>>>
> >>>>>>
> >>>>>
> >>>>>
> >>>>
> >>>
> >>>
> >>
> >
> >
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux