From patchwork Wed Mar 28 11:09:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Subhash Jadavani X-Patchwork-Id: 7509 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 4AEAC23E12 for ; Wed, 28 Mar 2012 11:09:54 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id E282BA18A69 for ; Wed, 28 Mar 2012 11:09:53 +0000 (UTC) Received: by iage36 with SMTP id e36so1778747iag.11 for ; Wed, 28 Mar 2012 04:09:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :x-ironport-av:from:to:cc:references:in-reply-to:subject:date :message-id:mime-version:x-mailer:thread-index:x-gm-message-state :content-type:content-transfer-encoding:content-language; bh=rqotCmH92aRdoigU/kBrgRoDl4n6nmGK7vZsxtlLPRE=; b=mp9fed/jHiMcQrW4WzDsru/Frk7z5S4Oivs7FTXWXNaw96xCqtc6afimLt7tLIYp70 8CU/N1Q32zPMt64f+9psM5nkCSJQGbnCt06Ck+6ljbZwf2eQzW1cQkLNmxyCSuWDPeHI VL8aqbCqrDSUP2nKhLOegZfQZooP+7R2DPh38/ZBldLKBj2snVf/DxJAea44vwuOgnrZ YtI/F4lDmeJMhvWSQsys66tL9CDMUE8EydQQV18gpYpyDdjdTIXyoDYPC/f5RUCXEgYr nZr6DRnkxogH+1jKeDweD0dRzOyTZMiXjmgWBNUGQKADNzyiDe4gRGHMgLPhBS/d+JUd VSSw== Received: by 10.50.194.226 with SMTP id hz2mr1721280igc.44.1332932993359; Wed, 28 Mar 2012 04:09:53 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.5.205 with SMTP id 13csp46703ibw; Wed, 28 Mar 2012 04:09:52 -0700 (PDT) Received: by 10.60.12.99 with SMTP id x3mr37310967oeb.38.1332932991800; Wed, 28 Mar 2012 04:09:51 -0700 (PDT) Received: from wolverine02.qualcomm.com (wolverine02.qualcomm.com. [199.106.114.251]) by mx.google.com with ESMTPS id kv10si1601176obc.47.2012.03.28.04.09.50 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 28 Mar 2012 04:09:51 -0700 (PDT) Received-SPF: neutral (google.com: 199.106.114.251 is neither permitted nor denied by best guess record for domain of subhashj@codeaurora.org) client-ip=199.106.114.251; Authentication-Results: mx.google.com; spf=neutral (google.com: 199.106.114.251 is neither permitted nor denied by best guess record for domain of subhashj@codeaurora.org) smtp.mail=subhashj@codeaurora.org X-IronPort-AV: E=McAfee;i="5400,1158,6662"; a="174200147" Received: from pdmz-css-vrrp.qualcomm.com (HELO mostmsg01.qualcomm.com) ([199.106.114.130]) by wolverine02.qualcomm.com with ESMTP/TLS/ADH-AES256-SHA; 28 Mar 2012 04:09:49 -0700 Received: from SUBHASHJ (pdmz-snip-v218.qualcomm.com [192.168.218.1]) by mostmsg01.qualcomm.com (Postfix) with ESMTPA id 39A3B10004A9; Wed, 28 Mar 2012 04:09:46 -0700 (PDT) From: "Subhash Jadavani" To: "'Saugata Das'" , "'Girish K S'" Cc: , , , "'Chris Ball'" References: <1323921517-31241-1-git-send-email-girish.shivananjappa@linaro.org> In-Reply-To: Subject: RE: [PATCH V2] mmc: core: Add host capability check for power class Date: Wed, 28 Mar 2012 16:39:44 +0530 Message-ID: <000401cd0cd3$4a6be470$df43ad50$@codeaurora.org> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 14.0 Thread-Index: Acy7Kjih3OImu7PBTzuwQo7cu8iQlBRpT0UQ X-Gm-Message-State: ALoCoQkyCyetVEzlpR0fbqi/Ybc02d+5/InSYv5eO2OrKhrfY3BvbvGBeDAyHfY8wMtkZJRwC0oV Content-Language: en-us > -----Original Message----- > From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc- > owner@vger.kernel.org] On Behalf Of Saugata Das > Sent: Thursday, December 15, 2011 6:35 PM > To: Girish K S > Cc: linux-mmc@vger.kernel.org; patches@linaro.org; linux-samsung- > soc@vger.kernel.org; subhashj@codeaurora.org; Chris Ball > Subject: Re: [PATCH V2] mmc: core: Add host capability check for power class > > On 15 December 2011 16:22, Girish K S > wrote: > > On 15 December 2011 15:34, Saugata Das wrote: > >> On 15 December 2011 09:28, Girish K S > wrote: > >>> This patch adds a check whether the host supports maximum current > >>> value obtained from the device's extended csd register for a > >>> selected interface voltage and frequency. > >>> > >>> cc: Chris Ball > >>> Signed-off-by: Girish K S > >>> --- > >>> Changes in v2: > >>>        deleted a unnecessary if else condition identified by subhash > >>> J Changes in v1: > >>>       reduced the number of comparisons as per Hein's suggestion > >>> > >>>  drivers/mmc/core/mmc.c   |   19 +++++++++++++++++++ > >>>  include/linux/mmc/card.h |    4 ++++ > >>>  2 files changed, 23 insertions(+), 0 deletions(-) > >>> > >>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index > >>> 006e932..b9ef777 100644 > >>> --- a/drivers/mmc/core/mmc.c > >>> +++ b/drivers/mmc/core/mmc.c > >>> @@ -688,6 +688,25 @@ static int mmc_select_powerclass(struct > >>> mmc_card *card, > >>>                pwrclass_val = (pwrclass_val & > >>> EXT_CSD_PWR_CL_4BIT_MASK) >> > >>>                                EXT_CSD_PWR_CL_4BIT_SHIFT; > >>> > >>> +       if (pwrclass_val >= MMC_MAX_CURRENT_800) > >>> +               pwrclass_val = MMC_MAX_CURRENT_800; > >>> +       else if (pwrclass_val >= MMC_MAX_CURRENT_600) > >>> +               pwrclass_val = MMC_MAX_CURRENT_600; > >>> +       else if (pwrclass_val >= MMC_MAX_CURRENT_400) > >>> +               pwrclass_val = MMC_MAX_CURRENT_400; > >>> +       else > >>> +               pwrclass_val = MMC_MAX_CURRENT_200; > >>> + > >>> +       if ((pwrclass_val == MMC_MAX_CURRENT_800) && > >>> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_800)) > >>> +               pwrclass_val = MMC_MAX_CURRENT_600; > >>> +       if ((pwrclass_val == MMC_MAX_CURRENT_600) && > >>> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_600)) > >>> +               pwrclass_val = MMC_MAX_CURRENT_400; > >>> +       if ((pwrclass_val == MMC_MAX_CURRENT_400) && > >>> +           !(card->host->caps & MMC_CAP_MAX_CURRENT_400)) > >>> +               pwrclass_val = MMC_MAX_CURRENT_200; > >>> + > >>>        /* If the power class is different from the default value */ > >>>        if (pwrclass_val > 0) { > >>>                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, > >> > >> It is not allowed to set the POWER_CLASS with any value other than > >> what is mentioned in the PWR_CL_ff_vvv or PWR_CL_DDR_ff_vvv  for > the > >> corresponding frequency, voltage. That is, if PWR_CL_200_195 is 14 > >> and we want to operate at HS200 then the only value allowed for > >> POWER_CLASS is 14. So, we need to check the PWR_CL numbers and > choose > >> the operating mode (HS200/DDR50/..) based on the platform capability > >> to support the current consumption and set the corresponding > >> POWER_CLASS value. > >> > >> Please refer to section 6.6.5 of the 4.5 spec. > > > > The upstreamed code reads the extended csd value based on the already > > set voltage level and frequency of host. So it will get the required > > power class value which can be set directly. Is my understanding > > correct? > > > > It is not enough to just check the voltage level and frequency. > Consider this example, host has capability to support > MMC_CAP_MAX_CURRENT_400, the PWR_CL_DDR_52_360 has the value 9 > (400mA) and PWR_CL_200_360 has the value 14 (800mA). Then even though > the host might be capable to run 200MHz clock and 3.6V, it can only enable > DDR at 52MHz and set 9 in POWER_CLASS. > > I think, in mmc_select_powerclass, we need to loop through the power > classes of all supported modes of transfer (HS200, DDR52, ... ) and choose the > mode which gives maximum bandwidth but falls within host capability of > current consumption. Then set this to POWER_CLASS byte and also use the > same information when setting HS_TIMING in mmc_init_card. Hi Saugata, Does the spec mandates you to set the power class to what is needed by frequency/voltage combination? I can't see that mentioned anywhere explicitly in eMMC4.5 spec (if it is mentioned in spec, please let me know section and line number). It may be still possible to set the power class lower than what is needed by frequency/voltage combination. Say for example, 8-bit HS200 (200MHz) with high voltage cards may specify power class (PWR_CL_200_3_6) value of 14 (800 mA) but that doesn't mean if you want the card to work in 8-bit HS200 mode, its POWER_CLASS value must be 14 (800mA). If host's VDD regulator is only capable of say 600mA then it may still set the POWER_CLASS to 12 (600 mA) which should be the indication to card that host power supply is capable of sourcing only 600mA and I would assume card will make sure that it doesn't draw anything more than that. Hi Girish, I see couple of other issues with your original power_class selection patch. 1. mmc_select_powerclass() function considers 2.7v to 3.2v VDD range as invalid. That's not correct. Valid high voltage range is from 2.7v to 3.6v. Is there a specific reason you have skipped the 2.7v to 3.2v VDD range? If not, I should post following change: 2. Currently in mmc_init_card(), power class selection is done if it's normal (DS or HS) or DDR or HS200 card. If power class selection fails (mmc_select_powerclass() returns error) for DS/HS/DDR cards, we are just printing the error and going ahead with the rest of the initialization where as if power class selection fails for HS200 cards, we are simply aborting the initialization and mark it as failed. There are my points: 1. Power class failure must be treated in same manner for DS/HS/DDR/HS200 cards 2. If you agree on first point then we need to decide whether power class selection failure is fatal enough to abort the MMC initialization? or we can just print the warning and go ahead with rest of the initialization in same bus speed mode? Regards, Subhash > > >> > >> > >>> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h > >>> index 9478a6b..c5e031a 100644 > >>> --- a/include/linux/mmc/card.h > >>> +++ b/include/linux/mmc/card.h > >>> @@ -195,6 +195,10 @@ struct mmc_part { > >>>  #define MMC_BLK_DATA_AREA_GP   (1<<2) > >>>  }; > >>> > >>> +#define MMC_MAX_CURRENT_200    (0) > >>> +#define MMC_MAX_CURRENT_400    (7) > >>> +#define MMC_MAX_CURRENT_600    (11) #define > MMC_MAX_CURRENT_800 > >>> +(13) > >>>  /* > >>>  * MMC device > >>>  */ > >>> -- > >>> 1.7.1 > >>> > >>> -- > >>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" > >>> in the body of a message to majordomo@vger.kernel.org More > majordomo > >>> info at  http://vger.kernel.org/majordomo-info.html > -- > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the > body of a message to majordomo@vger.kernel.org More majordomo info at > http://vger.kernel.org/majordomo-info.html --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -626,6 +626,11 @@ static int mmc_select_powerclass(struct mmc_card *card, else if (host->ios.clock <= 200000000) index = EXT_CSD_PWR_CL_200_195; break; + case MMC_VDD_27_28: + case MMC_VDD_28_29: + case MMC_VDD_29_30: + case MMC_VDD_30_31: + case MMC_VDD_31_32: case MMC_VDD_32_33: case MMC_VDD_33_34: case MMC_VDD_34_35: