RE: [PATCH V5] mmc: core: eMMC 4.5 Power Class Selection Feature

2011-12-04 Thread Subhash Jadavani
Hi Girish,

 -Original Message-
 From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc-
 ow...@vger.kernel.org] On Behalf Of Girish K S
 Sent: Friday, September 23, 2011 8:42 PM
 To: linux-...@vger.kernel.org
 Cc: c...@laptop.org; kgene@samsung.com; patc...@linaro.org; linux-
 samsung-...@vger.kernel.org; Girish K S
 Subject: [PATCH V5] mmc: core: eMMC 4.5 Power Class Selection Feature
 
 This patch adds the power class selection feature available
 for mmc versions 4.0 and above.
 During the enumeration stage before switching to the lower
 data bus, check if the power class is supported for the
 current bus width. If the power class is available then
 switch to the power class and use the higher data bus. If
 power class is not supported then switch to the lower data
 bus in a worst case.
 
 Signed-off-by: Girish K S girish.shivananja...@linaro.org
 ---
 Changes in v1:
 This version modifies the power_class_select function
 prototype.
 During device enumeration, when the host tries to read the
 extended
 csd register after switching to higher bus width, the read
 fails at
 higher bus width. So the power_class_select function is
 modified to
 reuse the extended csd register values read with 1 bit bus
 width.
 
 Changes in v2:
 This patch version removes some checkpatch error
 
 Changes in v3:
 updated with review comments made by chris ball. patch
 generated
 by rebasing to chris balls mmc-next branch.
 
 Changes in v4:
 updated with review comments.
 
 Changes in v5:
 Replace break statement with appropriate return error value in
   drivers/mmc/core/mmc.c for unsupported voltage range.
 
  drivers/mmc/core/mmc.c  |   96
 +++
  include/linux/mmc/mmc.h |   14 +++
  2 files changed, 110 insertions(+), 0 deletions(-)
 
 diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
 index 7adc30d..c2334d6 100644
 --- a/drivers/mmc/core/mmc.c
 +++ b/drivers/mmc/core/mmc.c
 @@ -532,6 +532,86 @@ static struct device_type mmc_type = {
  };
 
  /*
 + * Select the PowerClass for the current bus width
 + * If power class is defined for 4/8 bit bus in the
 + * extended CSD register, select it by executing the
 + * mmc_switch command.
 + */
 +static int mmc_select_powerclass(struct mmc_card *card,
 + unsigned int bus_width, u8 *ext_csd)
 +{
 + int err = 0;
 + unsigned int pwrclass_val;
 + unsigned int index = 0;
 + struct mmc_host *host;
 +
 + BUG_ON(!card);
 +
 + host = card-host;
 + BUG_ON(!host);
 +
 + if (ext_csd == NULL)
 + return 0;
 +
 + /* Power class selection is supported for versions = 4.0 */
 + if (card-csd.mmca_vsn  CSD_SPEC_VER_4)
 + return 0;
 +
 + /* Power class values are defined only for 4/8 bit bus */
 + if (bus_width == EXT_CSD_BUS_WIDTH_1)
 + return 0;
 +
 + switch (1  host-ios.vdd) {
 + case MMC_VDD_165_195:
 + if (host-ios.clock = 2600)
 + index = EXT_CSD_PWR_CL_26_195;
 + else if (host-ios.clock = 5200)
 + index = (bus_width = EXT_CSD_BUS_WIDTH_8) ?
 + EXT_CSD_PWR_CL_52_195 :
 + EXT_CSD_PWR_CL_DDR_52_195;
 + else if (host-ios.clock = 2)
 + index = EXT_CSD_PWR_CL_200_195;
 + break;
 + case MMC_VDD_32_33:
 + case MMC_VDD_33_34:
 + case MMC_VDD_34_35:
 + case MMC_VDD_35_36:
 + if (host-ios.clock = 2600)
 + index = EXT_CSD_PWR_CL_26_360;
 + else if (host-ios.clock = 5200)
 + index = (bus_width = EXT_CSD_BUS_WIDTH_8) ?
 + EXT_CSD_PWR_CL_52_360 :
 + EXT_CSD_PWR_CL_DDR_52_360;
 + else if (host-ios.clock = 2)
 + index = EXT_CSD_PWR_CL_200_360;
 + break;
 + default:
 + pr_warning(%s: Voltage range not supported 
 +for power class.\n, mmc_hostname(host));
 + return -EINVAL;
 + }
 +
 + pwrclass_val = ext_csd[index];
 +
 + if (bus_width  (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8))
 + pwrclass_val = (pwrclass_val  EXT_CSD_PWR_CL_8BIT_MASK) 
 + EXT_CSD_PWR_CL_8BIT_SHIFT;
 + else
 + pwrclass_val = (pwrclass_val  EXT_CSD_PWR_CL_4BIT_MASK) 
 + EXT_CSD_PWR_CL_4BIT_SHIFT;
 +
 + /* If the power class is different from the default value */
 + if (pwrclass_val  0) {
 + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 +  EXT_CSD_POWER_CLASS,
 +  pwrclass_val,
 +  0);
 + }

Sorry for late review. But I see an issue here. You are reading the max.
power

[PATCH V5] mmc: core: eMMC 4.5 Power Class Selection Feature

2011-09-23 Thread Girish K S
This patch adds the power class selection feature available
for mmc versions 4.0 and above.
During the enumeration stage before switching to the lower
data bus, check if the power class is supported for the
current bus width. If the power class is available then
switch to the power class and use the higher data bus. If
power class is not supported then switch to the lower data
bus in a worst case.

Signed-off-by: Girish K S girish.shivananja...@linaro.org
---
Changes in v1: 
This version modifies the power_class_select function prototype.
During device enumeration, when the host tries to read the extended
csd register after switching to higher bus width, the read fails at
higher bus width. So the power_class_select function is modified to
reuse the extended csd register values read with 1 bit bus width.

Changes in v2: 
This patch version removes some checkpatch error

Changes in v3: 
updated with review comments made by chris ball. patch generated
by rebasing to chris balls mmc-next branch.

Changes in v4: 
updated with review comments.

Changes in v5: 
Replace break statement with appropriate return error value in
drivers/mmc/core/mmc.c for unsupported voltage range.

 drivers/mmc/core/mmc.c  |   96 +++
 include/linux/mmc/mmc.h |   14 +++
 2 files changed, 110 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 7adc30d..c2334d6 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -532,6 +532,86 @@ static struct device_type mmc_type = {
 };
 
 /*
+ * Select the PowerClass for the current bus width
+ * If power class is defined for 4/8 bit bus in the
+ * extended CSD register, select it by executing the
+ * mmc_switch command.
+ */
+static int mmc_select_powerclass(struct mmc_card *card,
+   unsigned int bus_width, u8 *ext_csd)
+{
+   int err = 0;
+   unsigned int pwrclass_val;
+   unsigned int index = 0;
+   struct mmc_host *host;
+
+   BUG_ON(!card);
+
+   host = card-host;
+   BUG_ON(!host);
+
+   if (ext_csd == NULL)
+   return 0;
+
+   /* Power class selection is supported for versions = 4.0 */
+   if (card-csd.mmca_vsn  CSD_SPEC_VER_4)
+   return 0;
+
+   /* Power class values are defined only for 4/8 bit bus */
+   if (bus_width == EXT_CSD_BUS_WIDTH_1)
+   return 0;
+
+   switch (1  host-ios.vdd) {
+   case MMC_VDD_165_195:
+   if (host-ios.clock = 2600)
+   index = EXT_CSD_PWR_CL_26_195;
+   else if (host-ios.clock = 5200)
+   index = (bus_width = EXT_CSD_BUS_WIDTH_8) ?
+   EXT_CSD_PWR_CL_52_195 :
+   EXT_CSD_PWR_CL_DDR_52_195;
+   else if (host-ios.clock = 2)
+   index = EXT_CSD_PWR_CL_200_195;
+   break;
+   case MMC_VDD_32_33:
+   case MMC_VDD_33_34:
+   case MMC_VDD_34_35:
+   case MMC_VDD_35_36:
+   if (host-ios.clock = 2600)
+   index = EXT_CSD_PWR_CL_26_360;
+   else if (host-ios.clock = 5200)
+   index = (bus_width = EXT_CSD_BUS_WIDTH_8) ?
+   EXT_CSD_PWR_CL_52_360 :
+   EXT_CSD_PWR_CL_DDR_52_360;
+   else if (host-ios.clock = 2)
+   index = EXT_CSD_PWR_CL_200_360;
+   break;
+   default:
+   pr_warning(%s: Voltage range not supported 
+  for power class.\n, mmc_hostname(host));
+   return -EINVAL;
+   }
+
+   pwrclass_val = ext_csd[index];
+
+   if (bus_width  (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8))
+   pwrclass_val = (pwrclass_val  EXT_CSD_PWR_CL_8BIT_MASK) 
+   EXT_CSD_PWR_CL_8BIT_SHIFT;
+   else
+   pwrclass_val = (pwrclass_val  EXT_CSD_PWR_CL_4BIT_MASK) 
+   EXT_CSD_PWR_CL_4BIT_SHIFT;
+
+   /* If the power class is different from the default value */
+   if (pwrclass_val  0) {
+   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+EXT_CSD_POWER_CLASS,
+pwrclass_val,
+0);
+   }
+
+   return err;
+}
+
+/*
  * Handle the detection and initialisation of a card.
  *
  * In the case of a resume, oldcard will contain the card
@@ -787,6 +867,14 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
bus_width = bus_widths[idx];
if (bus_width == MMC_BUS_WIDTH_1)
ddr = 0; /* no DDR for 1-bit width */
+   err = mmc_select_powerclass(card, 

Re: [PATCH V5] mmc: core: eMMC 4.5 Power Class Selection Feature

2011-09-23 Thread Chris Ball
Hi Girish,

On Fri, Sep 23 2011, Girish K S wrote:
 This patch adds the power class selection feature available
 for mmc versions 4.0 and above.
 During the enumeration stage before switching to the lower
 data bus, check if the power class is supported for the
 current bus width. If the power class is available then
 switch to the power class and use the higher data bus. If
 power class is not supported then switch to the lower data
 bus in a worst case.

 Signed-off-by: Girish K S girish.shivananja...@linaro.org

Thanks, pushed to mmc-next for 3.2 now.

- Chris.
-- 
Chris Ball   c...@laptop.org   http://printf.net/
One Laptop Per Child
--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html