RE: [PATCH V2] mmc: core: eMMC4.5 Add the timeout for switch

2011-08-31 Thread Seungwon Jeon
Hi Girish,

Girish K S wrote:
> 
> V2- The datatype of the cmd6_timeout is changed from u8 to unsigned int,
> as it can hold a value upto 255*10=2550.
>   This patch adds the code to handle the default timeout
> for switch command.
> For eMMC 4.5 devices if timeout is not specified for the switch
> command while accessing a specific field,then the default timeout
> shall be used to timeout. Specification says there is no timeout
> defined while accessing BKOPS_START, SANITIZE_START, FLUSH_CACHE
> field(so these fields are excluded).
> 
> Signed-off-by: Girish K S 
> ---
>  drivers/mmc/core/mmc.c |5 +
>  drivers/mmc/core/mmc_ops.c |8 
>  include/linux/mmc/card.h   |1 +
>  include/linux/mmc/mmc.h|4 
>  4 files changed, 18 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 5700b1c..5b9fb6a 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -405,6 +405,11 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8
> *ext_csd)
>   if (card->ext_csd.rev >= 5)
>   card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
> 
> + if (card->ext_csd.rev > 5) {
> + /* (eMMC 4.5)timeout is expressed in units of 10 ms*/
> + card->ext_csd.cmd6_timeout = ext_csd[EXT_CSD_CMD6_TIME]*10;
> + }
> +
>   if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
>   card->erased_byte = 0xFF;
>   else
> diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
> index 770c3d0..c4d82f4 100644
> --- a/drivers/mmc/core/mmc_ops.c
> +++ b/drivers/mmc/core/mmc_ops.c
> @@ -394,6 +394,14 @@ int mmc_switch(struct mmc_card *card, u8 set, u8
> index, u8 value,
>   cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
>   cmd.cmd_timeout_ms = timeout_ms;
> 
> + /* timeout is not defined for below command indexes (eMMC 4.5) */
> + if ((timeout_ms == 0)   &&
> + (card->ext_csd->rev > 5)&&
> + (index != EXT_CSD_BKOPS_START)  &&
> + (index != EXT_CSD_SANITIZE_START)   &&
> + (index != EXT_CSD_FLUSH_CACHE))
> + cmd.cmd_timeout_ms = card->ext_csd->cmd6_timeout;
> +
mmc_switch doesn't need to take over '0' value for timeout_ms except for 
undefined timeout(Background operation, sanitize, etc)
It is possible and good to pass the argument of specific timeout_ms(including 
default cmd6 timeout) explicitly rather than '0',
if timeout value for cmd6 is defined.
Then, mmc_switch maybe doesn't need to handle timeout for some exception case.

>   err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
>   if (err)
>   return err;
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index b460fc2..ef88412 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -50,6 +50,7 @@ struct mmc_ext_csd {
>   u8  rel_sectors;
>   u8  rel_param;
>   u8  part_config;
> + unsigned intcmd6_timeout;   /* timeout in ms */
>   unsigned intpart_time;  /* Units: ms */
>   unsigned intsa_timeout; /* Units: 100ns */
>   unsigned inths_max_dtr;
> diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
> index 5a794cb..a23f836 100644
> --- a/include/linux/mmc/mmc.h
> +++ b/include/linux/mmc/mmc.h
> @@ -270,8 +270,11 @@ struct _mmc_csd {
>   * EXT_CSD fields
>   */
> 
> +#define EXT_CSD_FLUSH_CACHE  32  /* R/W */
>  #define EXT_CSD_PARTITION_ATTRIBUTE  156 /* R/W */
>  #define EXT_CSD_PARTITION_SUPPORT160 /* RO */
> +#define EXT_CSD_BKOPS_START  164 /* R/W */
> +#define EXT_CSD_SANITIZE_START   165 /* R/W */
>  #define EXT_CSD_WR_REL_PARAM 166 /* RO */
>  #define EXT_CSD_ERASE_GROUP_DEF  175 /* R/W */
>  #define EXT_CSD_PART_CONFIG  179 /* R/W */
> @@ -293,6 +296,7 @@ struct _mmc_csd {
>  #define EXT_CSD_SEC_ERASE_MULT   230 /* RO */
>  #define EXT_CSD_SEC_FEATURE_SUPPORT  231 /* RO */
>  #define EXT_CSD_TRIM_MULT232 /* RO */
> +#define EXT_CSD_CMD6_TIME248 /* RO */
> 
>  /*
>   * EXT_CSD field definitions
> --
> 1.7.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


RE: [PATCH 2/2] mmc: core: Add poweroff notify handling feature

2011-09-06 Thread Seungwon Jeon
Hi Girish K S,

I think short type is proper rather than long type by default.
Long type seems to be unacceptable in suspend regarding long timeout.
One question,
Is this patch considered for system power off besides suspend?

Beset regards,
Seungwon Jeon.

Girish K S wrote:
 
> Hi Mr Park,
> 
> On 5 September 2011 18:03, Kyungmin Park  wrote:
> > Hi Girish,
> >
> > I think it's still incomplete, does power off short function is called
> > at suspend properly?
> > there are some comments below.
> >
> > Thank you,
> > Kyungmin Park
> >
> > On Mon, Sep 5, 2011 at 8:49 PM, Girish K S
> >  wrote:
> >> This patch adds the handling of the poweroff notify feature
> >> during powerdown phase.
> >>
> >> Signed-off-by: Girish K S 
> >> ---
> >>  drivers/mmc/core/core.c  |   29 +
> >>  drivers/mmc/core/mmc.c   |3 +++
> >>  drivers/mmc/host/sdhci.c |   11 +++
> >>  include/linux/mmc/card.h |   29 +
> >>  include/linux/mmc/host.h |7 +--
> >>  5 files changed, 73 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> >> index a65e1ca..37b09d7 100644
> >> --- a/drivers/mmc/core/core.c
> >> +++ b/drivers/mmc/core/core.c
> >> @@ -1130,9 +1130,38 @@ static void mmc_power_up(struct mmc_host *host)
> >>
> >>  static void mmc_power_off(struct mmc_host *host)
> >>  {
> >> +   struct mmc_card *card = host->card;
> >> +   unsigned int notify_type;
> >> +   unsigned int timeout;
> >> +   int err;
> >> +
> >>host->ios.clock = 0;
> >>host->ios.vdd = 0;
> >>
> >> +   if (mmc_card_mmc(card) && mmc_card_powernotify_on(card)) {
> >> +
> >> +   if (host->power_notify_type == MMC_POWEROFF_NOTIFY_SHORT)
> {
> >> +   notify_type = EXT_CSD_POWER_OFF_SHORT;
> >> +   timeout = card->ext_csd.generic_cmd6_time;
> >> +   mmc_card_set_powernotify_short(card);
> >> +   } else {
> >> +   notify_type = EXT_CSD_POWER_OFF_LONG;
> >> +   timeout = card->ext_csd.power_off_longtime;
> >> +   mmc_card_set_powernotify_long(card);
> >> +   }
> >> +
> >> +   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> >> +   EXT_CSD_POWER_OFF_NOTIFICATION,
> >> +   notify_type, timeout);
> >> +
> >> +   if (err && err != -EBADMSG)
> >> +   printk(KERN_ERR "Device failed to respond "
> >> +   "within %d poweroff time."
> >> +   "forcefully powering down"
> >> +   "the device\n", timeout);
> >> +
> >> +   mmc_card_set_powernotify_off(card);
> >> +   }
> >>/*
> >> * Reset ocr mask to be the highest possible voltage supported
> for
> >> * this mmc host. This value will be used at next power up.
> >> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> >> index 2f06b37..b369c6f 100644
> >> --- a/drivers/mmc/core/mmc.c
> >> +++ b/drivers/mmc/core/mmc.c
> >> @@ -720,8 +720,11 @@ static int mmc_init_card(struct mmc_host *host,
> u32 ocr,
> >>EXT_CSD_POWER_OFF_NOTIFICATION,
> >>EXT_CSD_POWER_ON,
> >>card->ext_csd.generic_cmd6_time);
> >> +
> >>if (err && err != -EBADMSG)
> >>goto free_card;
> >> +
> >> +   mmc_card_set_powernotify_on(card);
> >>}
> >>
> >>/*
> >> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> >> index 0e02cc1..a24a31b 100644
> >> --- a/drivers/mmc/host/sdhci.c
> >> +++ b/drivers/mmc/host/sdhci.c
> >> @@ -2566,6 +2566,17 @@ int sdhci_add_host(struct sdhci_host *host)
> >>if (caps[1] & SDHCI_DRIVER_TYPE_D)
> >>mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
> >>
> >> +   if (mmc->caps == MMC_CAP_POWER_OFF

RE: [PATCH v2 2/2] mmc: core: Add Poweroff Notify handling

2011-09-06 Thread Seungwon Jeon
Hi Girish,

In case of system poweroff, mmc_power_off can be called indeed?
And I added some comments.

Best regards,
Seungwon Jeon.

Girish K S wrote:
> 
> This patch adds the power off notification handling
> during suspend and system poweroff.
> For suspend mode short timeout is used, whereas for the
> normal poweroff long timeout is used.
> 
> Signed-off-by: Girish K S 
> ---
>  drivers/mmc/core/core.c  |   33 +
>  drivers/mmc/core/mmc.c   |4 +++-
>  drivers/mmc/host/sdhci.c |   10 ++
>  include/linux/mmc/card.h |   19 +++
>  include/linux/mmc/host.h |4 
>  5 files changed, 69 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index a65e1ca..16da927 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -1130,9 +1130,38 @@ static void mmc_power_up(struct mmc_host *host)
> 
>  static void mmc_power_off(struct mmc_host *host)
>  {
> + struct mmc_card *card = host->card;
> + unsigned int notify_type;
> + unsigned int timeout;
> + int err;
> +
>   host->ios.clock = 0;
>   host->ios.vdd = 0;
> 
> + if (mmc_card_mmc(card) &&
> + (mmc_card_powernotify_on(card))) {
> +
> + if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
> + notify_type = EXT_CSD_POWER_OFF_SHORT;
> + timeout = card->ext_csd.generic_cmd6_time;
> + mmc_card_set_powernotify_short(card);
> + } else {
> + notify_type = EXT_CSD_POWER_OFF_LONG;
> + timeout = card->ext_csd.power_off_longtime;
> + mmc_card_set_powernotify_long(card);
> + }
> +
> + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> + EXT_CSD_POWER_OFF_NOTIFICATION,
> + notify_type, timeout);
> +
> + if (err && err != -EBADMSG)
> + printk(KERN_ERR "Device failed to respond "
> + "within %d poweroff time."
> + "forcefully powering down"
> + "the device\n", timeout);
> + }
> +
It'd be fine if one function take it above all.

>   /*
>* Reset ocr mask to be the highest possible voltage supported for
>* this mmc host. This value will be used at next power up.
> @@ -1147,6 +1176,8 @@ static void mmc_power_off(struct mmc_host *host)
>   host->ios.bus_width = MMC_BUS_WIDTH_1;
>   host->ios.timing = MMC_TIMING_LEGACY;
>   mmc_set_ios(host);
> + /*Set the card state to no notification after the poweroff*/
> + mmc_card_set_powernotify_off(card);
>  }
> 
>  /*
> @@ -2026,6 +2057,7 @@ int mmc_pm_notify(struct notifier_block
> *notify_block,
> 
>   spin_lock_irqsave(&host->lock, flags);
>   host->rescan_disable = 1;
> + host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>   spin_unlock_irqrestore(&host->lock, flags);
>   cancel_delayed_work_sync(&host->detect);
> 
> @@ -2048,6 +2080,7 @@ int mmc_pm_notify(struct notifier_block
> *notify_block,
> 
>   spin_lock_irqsave(&host->lock, flags);
>   host->rescan_disable = 0;
> + host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
>   spin_unlock_irqrestore(&host->lock, flags);
>   mmc_detect_change(host, 0);
> 
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 2f06b37..8868da8 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -715,13 +715,15 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
>* If the host supports the power_off_notify capability then
>* set the notification byte in the ext_csd register of device
>*/
> - if (host->caps & MMC_CAP_POWER_OFF_NOTIFY) {
> + if ((host->caps & MMC_CAP_POWER_OFF_NOTIFY) &&
> + (mmc_card_powernotify_off(card))) {

Previous version seems to be good. 

>   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>   EXT_CSD_POWER_OFF_NOTIFICATION,
>   EXT_CSD_POWER_ON,
>   card->ext_csd.generic_cmd6_time);
>   if (err && err != -EBADMSG)
>   goto free_card;
> + mmc_card_set_powernotify_on(card);

If err is -EBAD

RE: [PATCH v3 2/2] mmc: core: Add Poweroff Notify handling eMMC 4.5

2011-09-07 Thread Seungwon Jeon
Hi Girish,
Could you check my feedbacks about previous version?
There is something misunderstood.
I added comment below.

Best regards,
Seungwon Jeon.

Girish K S wrote:
> 
> This patch adds the power off notification handling
> during suspend and system poweroff.
> For suspend mode short timeout is used, whereas for the
> normal poweroff long timeout is used.
> 
> Signed-off-by: Girish K S 
> ---
>  drivers/mmc/core/core.c  |   33 +
>  drivers/mmc/core/mmc.c   |4 +++-
>  drivers/mmc/host/sdhci.c |   10 ++
>  include/linux/mmc/card.h |   19 +++
>  include/linux/mmc/host.h |4 
>  5 files changed, 69 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 91a0a74..da5d298 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -1130,9 +1130,38 @@ static void mmc_power_up(struct mmc_host *host)
> 
>  static void mmc_power_off(struct mmc_host *host)
>  {
> + struct mmc_card *card = host->card;
> + unsigned int notify_type;
> + unsigned int timeout;
> + int err;
> +
>   host->ios.clock = 0;
>   host->ios.vdd = 0;
> 
> + if (mmc_card_mmc(card) &&
> + (mmc_card_powernotify_on(card))) {
> +
> + if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
> + notify_type = EXT_CSD_POWER_OFF_SHORT;
> + timeout = card->ext_csd.generic_cmd6_time;
> + mmc_card_set_powernotify_short(card);
> + } else {
> + notify_type = EXT_CSD_POWER_OFF_LONG;
> + timeout = card->ext_csd.power_off_longtime;
> + mmc_card_set_powernotify_long(card);
> + }
> +
> + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> + EXT_CSD_POWER_OFF_NOTIFICATION,
> + notify_type, timeout);
> +
> + if (err && err != -EBADMSG)
> + printk(KERN_ERR "Device failed to respond "
> + "within %d poweroff time."
> + "forcefully powering down"
> + "the device\n", timeout);
> + }
> +
>   /*
>* Reset ocr mask to be the highest possible voltage supported for
>* this mmc host. This value will be used at next power up.
> @@ -1147,6 +1176,8 @@ static void mmc_power_off(struct mmc_host *host)
>   host->ios.bus_width = MMC_BUS_WIDTH_1;
>   host->ios.timing = MMC_TIMING_LEGACY;
>   mmc_set_ios(host);
> + /*Set the card state to no notification after the poweroff*/
> + mmc_card_set_powernotify_off(card);
>  }
> 
>  /*
> @@ -2022,6 +2053,7 @@ int mmc_pm_notify(struct notifier_block
> *notify_block,
> 
>   spin_lock_irqsave(&host->lock, flags);
>   host->rescan_disable = 1;
> + host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>   spin_unlock_irqrestore(&host->lock, flags);
>   cancel_delayed_work_sync(&host->detect);
> 
> @@ -2044,6 +2076,7 @@ int mmc_pm_notify(struct notifier_block
> *notify_block,
> 
>   spin_lock_irqsave(&host->lock, flags);
>   host->rescan_disable = 0;
> + host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
>   spin_unlock_irqrestore(&host->lock, flags);
>   mmc_detect_change(host, 0);
> 
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 2f06b37..8868da8 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -715,13 +715,15 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
>* If the host supports the power_off_notify capability then
>* set the notification byte in the ext_csd register of device
>*/
> - if (host->caps & MMC_CAP_POWER_OFF_NOTIFY) {
> + if ((host->caps & MMC_CAP_POWER_OFF_NOTIFY) &&
> + (mmc_card_powernotify_off(card))) {
>   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>   EXT_CSD_POWER_OFF_NOTIFICATION,
>   EXT_CSD_POWER_ON,
>   card->ext_csd.generic_cmd6_time);
>   if (err && err != -EBADMSG)
>   goto free_card;
> + mmc_card_set_powernotify_on(card);

Even if err is -EBADMSG, mmc_card_set_powernotify_on() will be executed.
In such cases, mmc_card

[PATCH] mmc: core: Fix the incorrect calculation for erase unit size.

2011-09-07 Thread Seungwon Jeon
Erase unit size of high capacity is multiple of 512KiB not 1024KiB.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/mmc.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index b148bb1..7991ecf 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -332,7 +332,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
card->ext_csd.hc_erase_timeout = 300 *
ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
card->ext_csd.hc_erase_size =
-   ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10;
+   ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 9;

card->ext_csd.rel_sectors = ext_csd[EXT_CSD_REL_WR_SEC_C];

--
1.7.0.4

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


[PATCH v2] mmc: core: Add default timeout value for CMD6.

2011-09-07 Thread Seungwon Jeon
EXT_CSD[248] includes the default maximum timeout for CMD6.
This field is added at eMMC4.5 Spec. And it can be used for default
timeout except for some operations which don't define the timeout(i.e.
background operation, sanitize, flush cache) in eMMC4.5 Spec.

Signed-off-by: Seungwon Jeon 
---
v2 : apply default maximum timeout of CMD6 which specific timeout is not 
defined.

 drivers/mmc/core/mmc.c   |   14 ++
 include/linux/mmc/card.h |1 +
 include/linux/mmc/mmc.h  |1 +
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 5700b1c..b148bb1 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -410,6 +410,10 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
else
card->erased_byte = 0x0;

+   if (card->ext_csd.rev >= 6)
+   card->ext_csd.generic_cmd6_time = 10 *
+   ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
+
 out:
return err;
 }
@@ -668,7 +672,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 */
if (card->ext_csd.enhanced_area_en) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-EXT_CSD_ERASE_GROUP_DEF, 1, 0);
+EXT_CSD_ERASE_GROUP_DEF, 1,
+card->ext_csd.generic_cmd6_time);

if (err && err != -EBADMSG)
goto free_card;
@@ -711,7 +716,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if ((card->ext_csd.hs_max_dtr != 0) &&
(host->caps & MMC_CAP_MMC_HIGHSPEED)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-EXT_CSD_HS_TIMING, 1, 0);
+EXT_CSD_HS_TIMING, 1,
+card->ext_csd.generic_cmd6_time);
if (err && err != -EBADMSG)
goto free_card;

@@ -783,7 +789,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_BUS_WIDTH,
 ext_csd_bits[idx][0],
-0);
+card->ext_csd.generic_cmd6_time);
if (!err) {
mmc_set_bus_width(card->host, bus_width);

@@ -806,7 +812,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_BUS_WIDTH,
 ext_csd_bits[idx][1],
-0);
+card->ext_csd.generic_cmd6_time);
}
if (err) {
printk(KERN_WARNING "%s: switch to bus width %d ddr %d "
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index b460fc2..e992fe3 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -52,6 +52,7 @@ struct mmc_ext_csd {
u8  part_config;
unsigned intpart_time;  /* Units: ms */
unsigned intsa_timeout; /* Units: 100ns */
+   unsigned intgeneric_cmd6_time;  /* Units: ms */
unsigned inths_max_dtr;
unsigned intsectors;
unsigned intcard_type;
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 5a794cb..e869f00 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -293,6 +293,7 @@ struct _mmc_csd {
 #define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
 #define EXT_CSD_SEC_FEATURE_SUPPORT231 /* RO */
 #define EXT_CSD_TRIM_MULT  232 /* RO */
+#define EXT_CSD_GENERIC_CMD6_TIME  248 /* RO */

 /*
  * EXT_CSD field definitions
--
1.7.0.4

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


RE: [PATCH v2] mmc: core: Add default timeout value for CMD6.

2011-09-08 Thread Seungwon Jeon
Thank you for comment.
I will apply it.

Best regards,
Seungwon Jeon.

Kyungmin Park wrote:
> 
> Acked-by: Kyungmin Park 
> 
> Nitpick: see below comments and typo.
> 
> On Thu, Sep 8, 2011 at 3:10 PM, Seungwon Jeon  wrote:
> > EXT_CSD[248] includes the default maximum timeout for CMD6.
> > This field is added at eMMC4.5 Spec. And it can be used for default
> > timeout except for some operations which don't define the timeout(i.e.
> > background operation, sanitize, flush cache) in eMMC4.5 Spec.
> >
> > Signed-off-by: Seungwon Jeon 
> > ---
> > v2 : apply default maximum timeout of CMD6 which specific timeout is not
> defined.
> >
> >  drivers/mmc/core/mmc.c   |   14 ++
> >  include/linux/mmc/card.h |1 +
> >  include/linux/mmc/mmc.h  |1 +
> >  3 files changed, 12 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> > index 5700b1c..b148bb1 100644
> > --- a/drivers/mmc/core/mmc.c
> > +++ b/drivers/mmc/core/mmc.c
> > @@ -410,6 +410,10 @@ static int mmc_read_ext_csd(struct mmc_card *card,
> u8 *ext_csd)
> >else
> >card->erased_byte = 0x0;
> >
> > +   if (card->ext_csd.rev >= 6)
> > +   card->ext_csd.generic_cmd6_time = 10 *
> > +   ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
> Even though generic_cmd6_time is cleared at card initialization. Make
> sure set the 0 when not eMMC v4.5 to make consistent with previous
> version and codes.
>  else
>card->ext_csd.generic_cmd6_time = 0;
Yes, it would be better.

> > +
> >  out:
> >return err;
> >  }
> > @@ -668,7 +672,8 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> > */
> >if (card->ext_csd.enhanced_area_en) {
> >err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > -EXT_CSD_ERASE_GROUP_DEF, 1, 0);
> > +EXT_CSD_ERASE_GROUP_DEF, 1,
> > +card->ext_csd.generic_cmd6_time);
> >
> >if (err && err != -EBADMSG)
> >goto free_card;
> > @@ -711,7 +716,8 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> >if ((card->ext_csd.hs_max_dtr != 0) &&
> >(host->caps & MMC_CAP_MMC_HIGHSPEED)) {
> >err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > -EXT_CSD_HS_TIMING, 1, 0);
> > +EXT_CSD_HS_TIMING, 1,
> > +card->ext_csd.generic_cmd6_time);
> >if (err && err != -EBADMSG)
> >goto free_card;
> >
> > @@ -783,7 +789,7 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> >err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > EXT_CSD_BUS_WIDTH,
> > ext_csd_bits[idx][0],
> > -0);
> > +card->ext_csd.generic_cmd6_time);
> >if (!err) {
> >mmc_set_bus_width(card->host, bus_width);
> >
> > @@ -806,7 +812,7 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> >err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > EXT_CSD_BUS_WIDTH,
> > ext_csd_bits[idx][1],
> > -0);
> > +card->ext_csd.generic_cmd6_time);
> >}
> >if (err) {
> >printk(KERN_WARNING "%s: switch to bus width %d
> ddr %d "
> > diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> > index b460fc2..e992fe3 100644
> > --- a/include/linux/mmc/card.h
> > +++ b/include/linux/mmc/card.h
> > @@ -52,6 +52,7 @@ struct mmc_ext_csd {
> >u8  part_config;
> >unsigned intpart_time;  /* Units: ms */
> >unsigned intsa_timeout; /* Units: 100ns */
> > +   unsigned intgeneric_cmd6_time;  /* Units: ms */
> The correct unit is 10ms
> 
> >unsigned inths_max_dtr;
> >unsigned intsectors;
> >

[PATCH v3] mmc: core: Add default timeout value for CMD6.

2011-09-08 Thread Seungwon Jeon
EXT_CSD[248] includes the default maximum timeout for CMD6.
This field is added at eMMC4.5 Spec. And it can be used for default
timeout except for some operations which don't define the timeout(i.e.
background operation, sanitize, flush cache) in eMMC4.5 Spec.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/mmc.c   |   19 +++
 include/linux/mmc/card.h |1 +
 include/linux/mmc/mmc.h  |1 +
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 5700b1c..a72d879 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -410,6 +410,15 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
else
card->erased_byte = 0x0;

+   if (card->ext_csd.rev >= 6)
+   card->ext_csd.generic_cmd6_time = 10 *
+   ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
+   else
+   card->ext_csd.generic_cmd6_time = 0;
+
 out:
return err;
 }
@@ -668,7 +677,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 */
if (card->ext_csd.enhanced_area_en) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-EXT_CSD_ERASE_GROUP_DEF, 1, 0);
+EXT_CSD_ERASE_GROUP_DEF, 1,
+card->ext_csd.generic_cmd6_time);

if (err && err != -EBADMSG)
goto free_card;
@@ -711,7 +721,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if ((card->ext_csd.hs_max_dtr != 0) &&
(host->caps & MMC_CAP_MMC_HIGHSPEED)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-EXT_CSD_HS_TIMING, 1, 0);
+EXT_CSD_HS_TIMING, 1,
+card->ext_csd.generic_cmd6_time);
if (err && err != -EBADMSG)
goto free_card;

@@ -783,7 +794,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_BUS_WIDTH,
 ext_csd_bits[idx][0],
-0);
+card->ext_csd.generic_cmd6_time);
if (!err) {
mmc_set_bus_width(card->host, bus_width);

@@ -806,7 +817,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_BUS_WIDTH,
 ext_csd_bits[idx][1],
-0);
+card->ext_csd.generic_cmd6_time);
}
if (err) {
printk(KERN_WARNING "%s: switch to bus width %d ddr %d "
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index b460fc2..b713abf 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -52,6 +52,7 @@ struct mmc_ext_csd {
u8  part_config;
unsigned intpart_time;  /* Units: ms */
unsigned intsa_timeout; /* Units: 100ns */
+   unsigned intgeneric_cmd6_time;  /* Units: 10ms */
unsigned inths_max_dtr;
unsigned intsectors;
unsigned intcard_type;
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 5a794cb..e869f00 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -293,6 +293,7 @@ struct _mmc_csd {
 #define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
 #define EXT_CSD_SEC_FEATURE_SUPPORT231 /* RO */
 #define EXT_CSD_TRIM_MULT  232 /* RO */
+#define EXT_CSD_GENERIC_CMD6_TIME  248 /* RO */

 /*
  * EXT_CSD field definitions
--
1.7.0.4

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


[PATCH] mmc: core: Add cache control for eMMC4.5 device

2011-09-08 Thread Seungwon Jeon
This patch adds cache feature of eMMC4.5 Spec.
If device supports cache capability, host can utilize some specific
operations.

Signed-off-by: Seungwon Jeon 
---
This patch is base on [PATCH v3] mmc: core: Add default timeout value for CMD6

 drivers/mmc/card/block.c |   14 ++
 drivers/mmc/core/core.c  |   62 ++
 drivers/mmc/core/mmc.c   |   23 +
 include/linux/mmc/card.h |2 +
 include/linux/mmc/core.h |2 +
 include/linux/mmc/host.h |3 ++
 include/linux/mmc/mmc.h  |3 ++
 7 files changed, 103 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index e702c61..84fa4bb 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -779,16 +779,18 @@ out:
 static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
 {
struct mmc_blk_data *md = mq->data;
+   struct mmc_card *card = md->queue.card;
+   int ret = 0;
+
+   ret = mmc_flush_cache(card);
+   if (ret)
+   ret = -EIO;

-   /*
-* No-op, only service this because we need REQ_FUA for reliable
-* writes.
-*/
spin_lock_irq(&md->lock);
-   __blk_end_request_all(req, 0);
+   __blk_end_request_all(req, ret);
spin_unlock_irq(&md->lock);

-   return 1;
+   return ret ? 0 : 1;
 }

 /*
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 557856b..14c2431 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1987,6 +1987,64 @@ int mmc_card_can_sleep(struct mmc_host *host)
 }
 EXPORT_SYMBOL(mmc_card_can_sleep);

+/*
+ * Flush the cache to the non-volatile storage.
+ */
+int mmc_flush_cache(struct mmc_card *card)
+{
+   struct mmc_host *host = card->host;
+   int err = 0;
+
+   if (!(host->caps & MMC_CAP_CACHE_CTRL))
+   return err;
+
+   if (mmc_card_mmc(card) &&
+   (card->ext_csd.cache_size > 0) &&
+   (card->ext_csd.cache_ctrl & 1)) {
+   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+   EXT_CSD_FLUSH_CACHE, 1, 0);
+   if (err)
+   pr_err("%s: cache flush error %d\n",
+   mmc_hostname(card->host), err);
+   }
+
+   return err;
+}
+EXPORT_SYMBOL(mmc_flush_cache);
+
+/*
+ * Turn the cache ON/OFF.
+ * Turning the cache OFF shall trigger flushing of the data
+ * to the non-volatile storage.
+ */
+int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
+{
+   struct mmc_card *card = host->card;
+   int err = 0;
+
+   if (!(host->caps & MMC_CAP_CACHE_CTRL))
+   return err;
+
+   if (card && mmc_card_mmc(card) &&
+   (card->ext_csd.cache_size > 0)) {
+   enable = !!enable;
+
+   if (card->ext_csd.cache_ctrl ^ enable)
+   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+   EXT_CSD_CACHE_CTRL, enable, 0);
+   if (err)
+   pr_err("%s: cache %s error %d\n",
+   mmc_hostname(card->host),
+   enable ? "on" : "off",
+   err);
+   else
+   card->ext_csd.cache_ctrl = enable;
+   }
+
+   return err;
+}
+EXPORT_SYMBOL(mmc_cache_ctrl);
+
 #ifdef CONFIG_PM

 /**
@@ -2001,6 +2059,9 @@ int mmc_suspend_host(struct mmc_host *host)
cancel_delayed_work(&host->disable);
cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
+   err = mmc_cache_ctrl(host, 0);
+   if (err)
+   goto out;

mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
@@ -2025,6 +2086,7 @@ int mmc_suspend_host(struct mmc_host *host)
if (!err && !mmc_card_keep_power(host))
mmc_power_off(host);

+out:
return err;
 }

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index ea58a0c..035112b 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -419,6 +419,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
 */
card->ext_csd.generic_cmd6_time = 0;

+   card->ext_csd.cache_size =
+   ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 |
+   ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
+   ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
+   ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+
 out:
return err;
 }
@@ -851,6 +857,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
}
}

+   /*
+* If cache size 

RE: [PATCH] mmc: core: Fix the incorrect calculation for erase unit size.

2011-09-13 Thread Seungwon Jeon
Chris Ball wrote:
> 
> Hi,
> 
> On Thu, Sep 08 2011, Seungwon Jeon wrote:
> > Erase unit size of high capacity is multiple of 512KiB not 1024KiB.
> 
> Could we have some more info, please?  What are the visible symptoms
> of the erase unit size being incorrect, how did you realize this was
> a problem, should this patch be applied to stable@, etc.

It is mentioned from eMMC Spec.
Erase unit size is defined in 512Kbyte * HC_ERASE_GRP_SIZE(EXT_CSD[224]).

Thanks.

> 
> Thanks,
> 
> - Chris.
> --
> Chris Ball  <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


RE: [PATCH] mmc: core: Fix the incorrect calculation for erase unit size.

2011-09-13 Thread Seungwon Jeon
Chris Ball wrote:
> 
> Hi,
> 
> On Tue, Sep 13 2011, Seungwon Jeon wrote:
> >> On Thu, Sep 08 2011, Seungwon Jeon wrote:
> >> > Erase unit size of high capacity is multiple of 512KiB not 1024KiB.
> >>
> >> Could we have some more info, please?  What are the visible symptoms
> >> of the erase unit size being incorrect, how did you realize this was
> >> a problem, should this patch be applied to stable@, etc.
> >
> > It is mentioned from eMMC Spec.
> > Erase unit size is defined in 512Kbyte * HC_ERASE_GRP_SIZE(EXT_CSD[224]).
> 
> You haven't answered any of the other questions I asked, though.

I didn't catch symptoms you expect. But it seems like plain.
I just noticed the difference with spec.

Best regards,
Seungwon Jeon.

> 
> Thanks,
> 
> - Chris.
> --
> Chris Ball  <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


RE: [PATCH v3] mmc: core: Add default timeout value for CMD6.

2011-09-21 Thread Seungwon Jeon
Hi Chris Ball,

Chris Ball wrote:
> Hi,
> 
> On Thu, Sep 08 2011, Seungwon Jeon wrote:
> > EXT_CSD[248] includes the default maximum timeout for CMD6.
> > This field is added at eMMC4.5 Spec. And it can be used for default
> > timeout except for some operations which don't define the timeout(i.e.
> > background operation, sanitize, flush cache) in eMMC4.5 Spec.
> >
> > Signed-off-by: Seungwon Jeon 
> > ---
> >  drivers/mmc/core/mmc.c   |   19 +++
> >  include/linux/mmc/card.h |1 +
> >  include/linux/mmc/mmc.h  |1 +
> >  3 files changed, 17 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> > index 5700b1c..a72d879 100644
> > --- a/drivers/mmc/core/mmc.c
> > +++ b/drivers/mmc/core/mmc.c
> > @@ -410,6 +410,15 @@ static int mmc_read_ext_csd(struct mmc_card *card,
> u8 *ext_csd)
> > else
> > card->erased_byte = 0x0;
> >
> > +   if (card->ext_csd.rev >= 6)
> > +   card->ext_csd.generic_cmd6_time = 10 *
> > +   ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
> > +   else
> > +   card->ext_csd.generic_cmd6_time = 0;
> > +
> >  out:
> > return err;
> >  }
> > @@ -668,7 +677,8 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> >  */
> 
> The patch is corrupt at this point:
> 
> patching file drivers/mmc/core/mmc.c
> patch:  malformed patch at line 39: @@ -668,7 +677,8 @@ static int
> mmc_init_card(struct mmc_host *host, u32 ocr,
Oops.
It's mistake. I'll resend.
> 
> - Chris.
> --
> Chris Ball  <http://printf.net/>
> One Laptop Per Child
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


[PATCH v4] mmc: core: Add default timeout value for CMD6.

2011-09-22 Thread Seungwon Jeon
EXT_CSD[248] includes the default maximum timeout for CMD6.
This field is added at eMMC4.5 Spec. And it can be used for default
timeout except for some operations which don't define the timeout(i.e.
background operation, sanitize, flush cache) in eMMC4.5 Spec.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/mmc.c   |   16 
 include/linux/mmc/card.h |1 +
 include/linux/mmc/mmc.h  |1 +
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 5700b1c..b2ee14a 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -410,6 +410,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
else
card->erased_byte = 0x0;

+   if (card->ext_csd.rev >= 6)
+   card->ext_csd.generic_cmd6_time = 10 *
+   ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
+   else
+   card->ext_csd.generic_cmd6_time = 0;
+
 out:
return err;
 }
@@ -668,7 +674,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 */
if (card->ext_csd.enhanced_area_en) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-EXT_CSD_ERASE_GROUP_DEF, 1, 0);
+EXT_CSD_ERASE_GROUP_DEF, 1,
+card->ext_csd.generic_cmd6_time);

if (err && err != -EBADMSG)
goto free_card;
@@ -711,7 +718,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if ((card->ext_csd.hs_max_dtr != 0) &&
(host->caps & MMC_CAP_MMC_HIGHSPEED)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-EXT_CSD_HS_TIMING, 1, 0);
+EXT_CSD_HS_TIMING, 1,
+card->ext_csd.generic_cmd6_time);
if (err && err != -EBADMSG)
goto free_card;

@@ -783,7 +791,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_BUS_WIDTH,
 ext_csd_bits[idx][0],
-0);
+card->ext_csd.generic_cmd6_time);
if (!err) {
mmc_set_bus_width(card->host, bus_width);

@@ -806,7 +814,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_BUS_WIDTH,
 ext_csd_bits[idx][1],
-0);
+card->ext_csd.generic_cmd6_time);
}
if (err) {
printk(KERN_WARNING "%s: switch to bus width %d ddr %d "
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index b460fc2..b713abf 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -52,6 +52,7 @@ struct mmc_ext_csd {
u8  part_config;
unsigned intpart_time;  /* Units: ms */
unsigned intsa_timeout; /* Units: 100ns */
+   unsigned intgeneric_cmd6_time;  /* Units: 10ms */
unsigned inths_max_dtr;
unsigned intsectors;
unsigned intcard_type;
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 5a794cb..e869f00 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -293,6 +293,7 @@ struct _mmc_csd {
 #define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
 #define EXT_CSD_SEC_FEATURE_SUPPORT231 /* RO */
 #define EXT_CSD_TRIM_MULT  232 /* RO */
+#define EXT_CSD_GENERIC_CMD6_TIME  248 /* RO */

 /*
  * EXT_CSD field definitions
--
1.7.0.4

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


RE: [PATCH v4] mmc: core: Add default timeout value for CMD6.

2011-09-22 Thread Seungwon Jeon
Hi,

J Freyensee wrote:
> 
> On 09/21/2011 07:12 PM, Seungwon Jeon wrote:
> > EXT_CSD[248] includes the default maximum timeout for CMD6.
> > This field is added at eMMC4.5 Spec. And it can be used for default
> > timeout except for some operations which don't define the timeout(i.e.
> > background operation, sanitize, flush cache) in eMMC4.5 Spec.
> 
> Out of curiosity, what cache is being refered to in 'flush cache' comment?
It is described in eMMC4.5 Spec.

Best regards,
Seungwon Jeon.
> >
> > Signed-off-by: Seungwon Jeon
> > ---
> >   drivers/mmc/core/mmc.c   |   16 
> >   include/linux/mmc/card.h |1 +
> >   include/linux/mmc/mmc.h  |1 +
> >   3 files changed, 14 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> > index 5700b1c..b2ee14a 100644
> > --- a/drivers/mmc/core/mmc.c
> > +++ b/drivers/mmc/core/mmc.c
> > @@ -410,6 +410,12 @@ static int mmc_read_ext_csd(struct mmc_card *card,
> u8 *ext_csd)
> > else
> > card->erased_byte = 0x0;
> >
> > +   if (card->ext_csd.rev>= 6)
> > +   card->ext_csd.generic_cmd6_time = 10 *
> > +   ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
> > +   else
> > +   card->ext_csd.generic_cmd6_time = 0;
> > +
> >   out:
> > return err;
> >   }
> > @@ -668,7 +674,8 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> >  */
> > if (card->ext_csd.enhanced_area_en) {
> > err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > -EXT_CSD_ERASE_GROUP_DEF, 1, 0);
> > +EXT_CSD_ERASE_GROUP_DEF, 1,
> > +card->ext_csd.generic_cmd6_time);
> >
> > if (err&&  err != -EBADMSG)
> > goto free_card;
> > @@ -711,7 +718,8 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> > if ((card->ext_csd.hs_max_dtr != 0)&&
> > (host->caps&  MMC_CAP_MMC_HIGHSPEED)) {
> > err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > -EXT_CSD_HS_TIMING, 1, 0);
> > +EXT_CSD_HS_TIMING, 1,
> > +card->ext_csd.generic_cmd6_time);
> > if (err&&  err != -EBADMSG)
> > goto free_card;
> >
> > @@ -783,7 +791,7 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> > err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> >  EXT_CSD_BUS_WIDTH,
> >  ext_csd_bits[idx][0],
> > -0);
> > +card->ext_csd.generic_cmd6_time);
> > if (!err) {
> > mmc_set_bus_width(card->host, bus_width);
> >
> > @@ -806,7 +814,7 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> > err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> >  EXT_CSD_BUS_WIDTH,
> >  ext_csd_bits[idx][1],
> > -0);
> > +card->ext_csd.generic_cmd6_time);
> > }
> > if (err) {
> > printk(KERN_WARNING "%s: switch to bus width %d ddr %d
> "
> > diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> > index b460fc2..b713abf 100644
> > --- a/include/linux/mmc/card.h
> > +++ b/include/linux/mmc/card.h
> > @@ -52,6 +52,7 @@ struct mmc_ext_csd {
> > u8  part_config;
> > unsigned intpart_time;  /* Units: ms */
> > unsigned intsa_timeout; /* Units: 100ns */
> > +   unsigned intgeneric_cmd6_time;  /* Units: 10ms */
> > unsigned inths_max_dtr;
> > unsigned intsectors;
> > unsigned intcard_type;
> > diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
> > index 5a794cb..e869f00 100644
> > --- a/include/linux/mmc/mmc.h
> > +++ b/include/linux/mmc/mmc.h
> > @@ -293,6 +293,7 @@ struct _mmc_csd {
> >   #define EXT_CSD_SEC_ERASE_MULT230 /* RO */
> >   #define EXT_CSD_SEC_FEATURE_SUPPORT   231 /* RO */
> >   #define EXT_CSD_TRIM_MULT 232 /* RO */
> > +#define EXT_CSD_GENERIC_CMD6_TIME  248 /* RO */
> >
> >   /*
> >* EXT_CSD field definitions
> > --
> > 1.7.0.4
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> > the body of a message to majord...@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 
> --
> J (James/Jay) Freyensee
> Storage Technology Group
> Intel Corporation

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


[PATCH] mmc: dw_mmc: Support predefined multiple block transfers.

2011-09-26 Thread Seungwon Jeon
This patch adds the support for predefined multiple block read/write.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/host/dw_mmc.c |   32 ++--
 1 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 0ed1d28..36a5576 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -588,11 +588,10 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
mci_writel(host, CTYPE, (slot->ctype << slot->id));
 }

-static void dw_mci_start_request(struct dw_mci *host,
-struct dw_mci_slot *slot)
+static void __dw_mci_start_request(struct dw_mci *host,
+struct dw_mci_slot *slot, struct mmc_command 
*cmd)
 {
struct mmc_request *mrq;
-   struct mmc_command *cmd;
struct mmc_data *data;
u32 cmdflags;

@@ -610,14 +609,13 @@ static void dw_mci_start_request(struct dw_mci *host,
host->completed_events = 0;
host->data_status = 0;

-   data = mrq->data;
+   data = cmd->data;
if (data) {
dw_mci_set_timeout(host);
mci_writel(host, BYTCNT, data->blksz*data->blocks);
mci_writel(host, BLKSIZ, data->blksz);
}

-   cmd = mrq->cmd;
cmdflags = dw_mci_prepare_command(slot->mmc, cmd);

/* this is the first command, send the initialization clock */
@@ -635,6 +633,16 @@ static void dw_mci_start_request(struct dw_mci *host,
host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop);
 }

+static void dw_mci_start_request(struct dw_mci *host,
+struct dw_mci_slot *slot)
+{
+   struct mmc_request *mrq = slot->mrq;
+   struct mmc_command *cmd;
+
+   cmd = mrq->sbc ? mrq->sbc : mrq->cmd;
+   __dw_mci_start_request(host, slot, cmd);
+}
+
 /* must be called with host->lock held */
 static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
 struct mmc_request *mrq)
@@ -889,7 +897,13 @@ static void dw_mci_tasklet_func(unsigned long priv)
cmd = host->cmd;
host->cmd = NULL;
set_bit(EVENT_CMD_COMPLETE, &host->completed_events);
-   dw_mci_command_complete(host, host->mrq->cmd);
+   dw_mci_command_complete(host, cmd);
+   if ((cmd == host->mrq->sbc) && !cmd->error) {
+   prev_state = state = STATE_SENDING_CMD;
+   __dw_mci_start_request(host, host->cur_slot, 
host->mrq->cmd);
+   goto unlock;
+   }
+
if (!host->mrq->data || cmd->error) {
dw_mci_request_end(host, host->mrq);
goto unlock;
@@ -967,6 +981,12 @@ static void dw_mci_tasklet_func(unsigned long priv)
goto unlock;
}

+   if (host->mrq->sbc && !data->error) {
+   data->stop->error = 0;
+   dw_mci_request_end(host, host->mrq);
+   goto unlock;
+   }
+
prev_state = state = STATE_SENDING_STOP;
if (!data->error)
send_stop_cmd(host, data);
--
1.7.0.4


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


RE: [PATCH] mmc: dw_mmc: Support predefined multiple block transfers.

2011-09-26 Thread Seungwon Jeon
Andrei Warkentin wrote:
> Hi Seungwon,
> 
> - Original Message -
> > From: "Seungwon Jeon" 
> > To: linux-...@vger.kernel.org
> > Cc: "Chris Ball" , linux-samsung-soc@vger.kernel.org,
> "kgene kim" , "dh han"
> > , "Seungwon Jeon" 
> > Sent: Monday, September 26, 2011 7:46:59 AM
> > Subject: [PATCH] mmc: dw_mmc: Support predefined multiple block
> transfers.
> >
> > This patch adds the support for predefined multiple block read/write.
> >
> > Signed-off-by: Seungwon Jeon 
> 
> Without knowing much about dw_mmc host, your logic otherwise looks ok,
> given what
> I've previously done for SDHCI as far as CMD23/Auto-CMD23 enhancement.
> Just curious, what eMMC cards did you test this on, and what improvement
> did you see?

Thank you for review.
As you done, predefined transfer is required for reliable writes and eMMC4.5 
feature.
Sadly, I didn't gain an improvement in my case.
(I don't know whether I can clarify the tested eMMC card, just one sample.)

Best regards,
Seungwon Jeon.

> 
> Acked-by: Andrei Warkentin 
> 
> Thanks,
> A
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


[PATCH] mmc: dw_mmc: Support predefined multiple block transfers.

2011-09-27 Thread Seungwon Jeon
This patch adds the support for predefined multiple block read/write.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/host/dw_mmc.c |   32 ++--
 1 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 0ed1d28..36a5576 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -588,11 +588,10 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
mci_writel(host, CTYPE, (slot->ctype << slot->id));
 }

-static void dw_mci_start_request(struct dw_mci *host,
-struct dw_mci_slot *slot)
+static void __dw_mci_start_request(struct dw_mci *host,
+struct dw_mci_slot *slot, struct mmc_command 
*cmd)
 {
struct mmc_request *mrq;
-   struct mmc_command *cmd;
struct mmc_data *data;
u32 cmdflags;

@@ -610,14 +609,13 @@ static void dw_mci_start_request(struct dw_mci *host,
host->completed_events = 0;
host->data_status = 0;

-   data = mrq->data;
+   data = cmd->data;
if (data) {
dw_mci_set_timeout(host);
mci_writel(host, BYTCNT, data->blksz*data->blocks);
mci_writel(host, BLKSIZ, data->blksz);
}

-   cmd = mrq->cmd;
cmdflags = dw_mci_prepare_command(slot->mmc, cmd);

/* this is the first command, send the initialization clock */
@@ -635,6 +633,16 @@ static void dw_mci_start_request(struct dw_mci *host,
host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop);
 }

+static void dw_mci_start_request(struct dw_mci *host,
+struct dw_mci_slot *slot)
+{
+   struct mmc_request *mrq = slot->mrq;
+   struct mmc_command *cmd;
+
+   cmd = mrq->sbc ? mrq->sbc : mrq->cmd;
+   __dw_mci_start_request(host, slot, cmd);
+}
+
 /* must be called with host->lock held */
 static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
 struct mmc_request *mrq)
@@ -889,7 +897,13 @@ static void dw_mci_tasklet_func(unsigned long priv)
cmd = host->cmd;
host->cmd = NULL;
set_bit(EVENT_CMD_COMPLETE, &host->completed_events);
-   dw_mci_command_complete(host, host->mrq->cmd);
+   dw_mci_command_complete(host, cmd);
+   if ((cmd == host->mrq->sbc) && !cmd->error) {
+   prev_state = state = STATE_SENDING_CMD;
+   __dw_mci_start_request(host, host->cur_slot, 
host->mrq->cmd);
+   goto unlock;
+   }
+
if (!host->mrq->data || cmd->error) {
dw_mci_request_end(host, host->mrq);
goto unlock;
@@ -967,6 +981,12 @@ static void dw_mci_tasklet_func(unsigned long priv)
goto unlock;
}

+   if (host->mrq->sbc && !data->error) {
+   data->stop->error = 0;
+   dw_mci_request_end(host, host->mrq);
+   goto unlock;
+   }
+
prev_state = state = STATE_SENDING_STOP;
if (!data->error)
send_stop_cmd(host, data);
--
1.7.0.4

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


RE: [PATCH] mmc: dw_mmc: Support predefined multiple block transfers.

2011-09-27 Thread Seungwon Jeon
This is  a duplicate patch from our security machine.
Please ignore this resending.

Best regards,
Seungwon Jeon.
> 
> This patch adds the support for predefined multiple block read/write.
> 
> Signed-off-by: Seungwon Jeon 
> ---
>  drivers/mmc/host/dw_mmc.c |   32 ++--
>  1 files changed, 26 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 0ed1d28..36a5576 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -588,11 +588,10 @@ static void dw_mci_setup_bus(struct dw_mci_slot
> *slot)
>   mci_writel(host, CTYPE, (slot->ctype << slot->id));
>  }
> 
> -static void dw_mci_start_request(struct dw_mci *host,
> -  struct dw_mci_slot *slot)
> +static void __dw_mci_start_request(struct dw_mci *host,
> +  struct dw_mci_slot *slot, struct mmc_command
> *cmd)
>  {
>   struct mmc_request *mrq;
> - struct mmc_command *cmd;
>   struct mmc_data *data;
>   u32 cmdflags;
> 
> @@ -610,14 +609,13 @@ static void dw_mci_start_request(struct dw_mci *host,
>   host->completed_events = 0;
>   host->data_status = 0;
> 
> - data = mrq->data;
> + data = cmd->data;
>   if (data) {
>   dw_mci_set_timeout(host);
>   mci_writel(host, BYTCNT, data->blksz*data->blocks);
>   mci_writel(host, BLKSIZ, data->blksz);
>   }
> 
> - cmd = mrq->cmd;
>   cmdflags = dw_mci_prepare_command(slot->mmc, cmd);
> 
>   /* this is the first command, send the initialization clock */
> @@ -635,6 +633,16 @@ static void dw_mci_start_request(struct dw_mci *host,
>   host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq-
> >stop);
>  }
> 
> +static void dw_mci_start_request(struct dw_mci *host,
> +  struct dw_mci_slot *slot)
> +{
> + struct mmc_request *mrq = slot->mrq;
> + struct mmc_command *cmd;
> +
> + cmd = mrq->sbc ? mrq->sbc : mrq->cmd;
> + __dw_mci_start_request(host, slot, cmd);
> +}
> +
>  /* must be called with host->lock held */
>  static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot
> *slot,
>struct mmc_request *mrq)
> @@ -889,7 +897,13 @@ static void dw_mci_tasklet_func(unsigned long priv)
>   cmd = host->cmd;
>   host->cmd = NULL;
>   set_bit(EVENT_CMD_COMPLETE, &host->completed_events);
> - dw_mci_command_complete(host, host->mrq->cmd);
> + dw_mci_command_complete(host, cmd);
> + if ((cmd == host->mrq->sbc) && !cmd->error) {
> + prev_state = state = STATE_SENDING_CMD;
> + __dw_mci_start_request(host, host->cur_slot,
> host->mrq->cmd);
> + goto unlock;
> + }
> +
>   if (!host->mrq->data || cmd->error) {
>   dw_mci_request_end(host, host->mrq);
>   goto unlock;
> @@ -967,6 +981,12 @@ static void dw_mci_tasklet_func(unsigned long priv)
>   goto unlock;
>   }
> 
> + if (host->mrq->sbc && !data->error) {
> + data->stop->error = 0;
> + dw_mci_request_end(host, host->mrq);
> + goto unlock;
> + }
> +
>   prev_state = state = STATE_SENDING_STOP;
>   if (!data->error)
>   send_stop_cmd(host, data);
> --
> 1.7.0.4

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


RE: [PATCH] mmc: dw_mmc: Support predefined multiple block transfers.

2011-09-28 Thread Seungwon Jeon
Andrei Warkentin wrote:
> 2011/9/26 Seungwon Jeon :
> > Andrei Warkentin wrote:
> >> Hi Seungwon,
> >>
> >> - Original Message -
> >> > From: "Seungwon Jeon" 
> >> > To: linux-...@vger.kernel.org
> >> > Cc: "Chris Ball" , linux-samsung-soc@vger.kernel.org,
> >> "kgene kim" , "dh han"
> >> > , "Seungwon Jeon" 
> >> > Sent: Monday, September 26, 2011 7:46:59 AM
> >> > Subject: [PATCH] mmc: dw_mmc: Support predefined multiple block
> >> transfers.
> >> >
> >> > This patch adds the support for predefined multiple block read/write.
> >> >
> >> > Signed-off-by: Seungwon Jeon 
> >>
> >> Without knowing much about dw_mmc host, your logic otherwise looks ok,
> >> given what
> >> I've previously done for SDHCI as far as CMD23/Auto-CMD23 enhancement.
> >> Just curious, what eMMC cards did you test this on, and what
> improvement
> >> did you see?
> >
> > Thank you for review.
> > As you done, predefined transfer is required for reliable writes and
> eMMC4.5 feature.
> > Sadly, I didn't gain an improvement in my case.
> > (I don't know whether I can clarify the tested eMMC card, just one
> sample.)
> >
> 
> So far I've seen some Sandisk cards have a noticeable real-life
> improvement (30%) over
> open-ended transfers.
> 
> You might wish to try out https://github.com/andreiw/superalign to be
> certain.

I had already tested this patch with IOZONE, but I found no difference.
Maybe a result depends on eMMC device.
As your recommend, I applied above benchmark tool. 
Predefined transfer seems like a little better, but there is no difference.

Thanks.
Seungwon Jeon.

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

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


RE: [PATCH v2] mmc: core: Add default timeout value for CMD6.

2011-09-28 Thread Seungwon Jeon
Girish K S wrote:
> 
> Hi Jeon,
> 
> I tried to apply your patch to the latest Chris-mmc/mmc-next branch.
> but the patch fails. can you please check
> err message.
> 
> error: patch failed: include/linux/mmc/card.h:52
> error: include/linux/mmc/card.h: patch does not apply
> error: patch failed: include/linux/mmc/mmc.h:293
> error: include/linux/mmc/mmc.h: patch does not apply
> Patch failed at 0001 mmc: core: Add default timeout value for CMD6.

Thank you for informing me.
But V4 is latest patch.
Anyway, since I has submitted this patch, several patches were updated.
So base branch is changed. Could I update this patch?

Best regards,
Seungwon Jeon.
> 
> regards
> Girish K S
> > EXT_CSD[248] includes the default maximum timeout for CMD6.
> > This field is added at eMMC4.5 Spec. And it can be used for default
> > timeout except for some operations which don't define the timeout(i.e.
> > background operation, sanitize, flush cache) in eMMC4.5 Spec.
> >
> > Signed-off-by: Seungwon Jeon 
> > ---
> > v2 : apply default maximum timeout of CMD6 which specific timeout is not
> defined.
> >
> >  drivers/mmc/core/mmc.c   |   14 ++
> >  include/linux/mmc/card.h |1 +
> >  include/linux/mmc/mmc.h  |1 +
> >  3 files changed, 12 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> > index 5700b1c..b148bb1 100644
> > --- a/drivers/mmc/core/mmc.c
> > +++ b/drivers/mmc/core/mmc.c
> > @@ -410,6 +410,10 @@ static int mmc_read_ext_csd(struct mmc_card *card,
> u8 *ext_csd)
> >else
> >card->erased_byte = 0x0;
> >
> > +   if (card->ext_csd.rev >= 6)
> > +   card->ext_csd.generic_cmd6_time = 10 *
> > +   ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
> > +
> >  out:
> >return err;
> >  }
> > @@ -668,7 +672,8 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> > */
> >if (card->ext_csd.enhanced_area_en) {
> >err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > -EXT_CSD_ERASE_GROUP_DEF, 1, 0);
> > +EXT_CSD_ERASE_GROUP_DEF, 1,
> > +card->ext_csd.generic_cmd6_time);
> >
> >if (err && err != -EBADMSG)
> >goto free_card;
> > @@ -711,7 +716,8 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> >if ((card->ext_csd.hs_max_dtr != 0) &&
> >(host->caps & MMC_CAP_MMC_HIGHSPEED)) {
> >err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > -EXT_CSD_HS_TIMING, 1, 0);
> > +EXT_CSD_HS_TIMING, 1,
> > +card->ext_csd.generic_cmd6_time);
> >if (err && err != -EBADMSG)
> >goto free_card;
> >
> > @@ -783,7 +789,7 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> >err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > EXT_CSD_BUS_WIDTH,
> > ext_csd_bits[idx][0],
> > -0);
> > +card->ext_csd.generic_cmd6_time);
> >if (!err) {
> >mmc_set_bus_width(card->host, bus_width);
> >
> > @@ -806,7 +812,7 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> >err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > EXT_CSD_BUS_WIDTH,
> > ext_csd_bits[idx][1],
> > -0);
> > +card->ext_csd.generic_cmd6_time);
> >}
> >if (err) {
> >printk(KERN_WARNING "%s: switch to bus width %d
> ddr %d "
> > diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> > index b460fc2..e992fe3 100644
> > --- a/include/linux/mmc/card.h
> > +++ b/include/linux/mmc/card.h
> > @@ -52,6 +52,7 @@ struct mmc_ext_csd {
> >u8  part_config;
> >unsigned intpart_time;  /* Units: ms */
> >unsigned intsa_timeout; /* Units: 100ns */
> > +   unsign

RE: [PATCH] mmc: dw_mmc: Support predefined multiple block transfers.

2011-10-05 Thread Seungwon Jeon
Jaehoon Chung wrote:
> 
> Hi Mr.Jeon
> 
> One question...if we used predefined transfer, didn't send stop-command?
> then i think that didn't need to enter this condition..how about this?
> 
> In __dw_mci_start_reqeust() function(at your patch)
> 
> if (mrq->stop)
>   host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop);
> 
> If i misunderstood something, plz let me know...Thanks.
Yes, predefined transfer doesn't send stop command normally.
But if transfer error is occurred, stop command is required.

Thank you for test.
Best regards,
Seungwon Jeon.
> 
> Tested-by: Jaehoon Chung 
> 
> On 09/28/2011 05:23 PM, Seungwon Jeon wrote:
> 
> > Andrei Warkentin wrote:
> >> 2011/9/26 Seungwon Jeon :
> >>> Andrei Warkentin wrote:
> >>>> Hi Seungwon,
> >>>>
> >>>> - Original Message -
> >>>>> From: "Seungwon Jeon" 
> >>>>> To: linux-...@vger.kernel.org
> >>>>> Cc: "Chris Ball" , linux-samsung-soc@vger.kernel.org,
> >>>> "kgene kim" , "dh han"
> >>>>> , "Seungwon Jeon" 
> >>>>> Sent: Monday, September 26, 2011 7:46:59 AM
> >>>>> Subject: [PATCH] mmc: dw_mmc: Support predefined multiple block
> >>>> transfers.
> >>>>>
> >>>>> This patch adds the support for predefined multiple block read/write.
> >>>>>
> >>>>> Signed-off-by: Seungwon Jeon 
> >>>>
> >>>> Without knowing much about dw_mmc host, your logic otherwise looks ok,
> >>>> given what
> >>>> I've previously done for SDHCI as far as CMD23/Auto-CMD23 enhancement.
> >>>> Just curious, what eMMC cards did you test this on, and what
> >> improvement
> >>>> did you see?
> >>>
> >>> Thank you for review.
> >>> As you done, predefined transfer is required for reliable writes and
> >> eMMC4.5 feature.
> >>> Sadly, I didn't gain an improvement in my case.
> >>> (I don't know whether I can clarify the tested eMMC card, just one
> >> sample.)
> >>>
> >>
> >> So far I've seen some Sandisk cards have a noticeable real-life
> >> improvement (30%) over
> >> open-ended transfers.
> >>
> >> You might wish to try out https://github.com/andreiw/superalign to be
> >> certain.
> >
> > I had already tested this patch with IOZONE, but I found no difference.
> > Maybe a result depends on eMMC device.
> > As your recommend, I applied above benchmark tool.
> > Predefined transfer seems like a little better, but there is no
> difference.
> >
> > Thanks.
> > Seungwon Jeon.
> >
> >>
> >> A
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> >> the body of a message to majord...@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 majord...@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 majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


RE: [PATCH v4] mmc: core: Add default timeout value for CMD6.

2011-10-05 Thread Seungwon Jeon
Adrian Hunter wrote:
> On 22/09/11 05:12, Seungwon Jeon wrote:
> > EXT_CSD[248] includes the default maximum timeout for CMD6.
> > This field is added at eMMC4.5 Spec. And it can be used for default
> > timeout except for some operations which don't define the timeout(i.e.
> > background operation, sanitize, flush cache) in eMMC4.5 Spec.
> >
> > Signed-off-by: Seungwon Jeon
> 
> What about the mmc_switch() in mmc_select_powerclass()?
During submission with revision, mmc_select_powerclass() is not considered.
I'll apply it.
Thank you for catch.

> 
> > ---
> >   drivers/mmc/core/mmc.c   |   16 
> >   include/linux/mmc/card.h |1 +
> >   include/linux/mmc/mmc.h  |1 +
> >   3 files changed, 14 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> > index 5700b1c..b2ee14a 100644
> > --- a/drivers/mmc/core/mmc.c
> > +++ b/drivers/mmc/core/mmc.c
> > @@ -410,6 +410,12 @@ static int mmc_read_ext_csd(struct mmc_card *card,
> u8 *ext_csd)
> > else
> > card->erased_byte = 0x0;
> >
> > +   if (card->ext_csd.rev>= 6)
> > +   card->ext_csd.generic_cmd6_time = 10 *
> > +   ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
> > +   else
> > +   card->ext_csd.generic_cmd6_time = 0;
> > +
> >   out:
> > return err;
> >   }
> > @@ -668,7 +674,8 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> >  */
> > if (card->ext_csd.enhanced_area_en) {
> > err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > -EXT_CSD_ERASE_GROUP_DEF, 1, 0);
> > +EXT_CSD_ERASE_GROUP_DEF, 1,
> > +card->ext_csd.generic_cmd6_time);
> >
> > if (err&&  err != -EBADMSG)
> > goto free_card;
> > @@ -711,7 +718,8 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> > if ((card->ext_csd.hs_max_dtr != 0)&&
> > (host->caps&  MMC_CAP_MMC_HIGHSPEED)) {
> > err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > -EXT_CSD_HS_TIMING, 1, 0);
> > +EXT_CSD_HS_TIMING, 1,
> > +card->ext_csd.generic_cmd6_time);
> > if (err&&  err != -EBADMSG)
> > goto free_card;
> >
> > @@ -783,7 +791,7 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> > err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> >  EXT_CSD_BUS_WIDTH,
> >  ext_csd_bits[idx][0],
> > -0);
> > +card->ext_csd.generic_cmd6_time);
> > if (!err) {
> > mmc_set_bus_width(card->host, bus_width);
> >
> > @@ -806,7 +814,7 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
> > err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> >  EXT_CSD_BUS_WIDTH,
> >  ext_csd_bits[idx][1],
> > -0);
> > +card->ext_csd.generic_cmd6_time);
> > }
> > if (err) {
> > printk(KERN_WARNING "%s: switch to bus width %d ddr %d
> "
> > diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> > index b460fc2..b713abf 100644
> > --- a/include/linux/mmc/card.h
> > +++ b/include/linux/mmc/card.h
> > @@ -52,6 +52,7 @@ struct mmc_ext_csd {
> > u8  part_config;
> > unsigned intpart_time;  /* Units: ms */
> > unsigned intsa_timeout; /* Units: 100ns */
> > +   unsigned intgeneric_cmd6_time;  /* Units: 10ms */
> 
> 
> Units are "ms" not "10ms" because you multiply by 10 in mmc_read_ext_csd
The above comment is aimed to highlight 10ms is mentioned in spec.
Yes, Units of generic_cmd6_time is "ms".
Depending on point of view, the meaning can be construed differently.
I will apply it.

> 
> > unsigned inths_max_dtr;
> > unsigned intsectors;
> > unsigned intcard_type;
> > diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
> > index 5a794cb..e86

[PATCH v5] mmc: core: Add default timeout value for CMD6.

2011-10-05 Thread Seungwon Jeon
EXT_CSD[248] includes the default maximum timeout for CMD6.
This field is added at eMMC4.5 Spec. And it can be used for default
timeout except for some operations which don't define the timeout(i.e.
background operation, sanitize, flush cache) in eMMC4.5 Spec.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/mmc.c   |   18 +-
 include/linux/mmc/card.h |1 +
 include/linux/mmc/mmc.h  |1 +
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index c632b1f..c37b8d2 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -414,6 +414,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
else
card->erased_byte = 0x0;

+   if (card->ext_csd.rev >= 6)
+   card->ext_csd.generic_cmd6_time = 10 *
+   ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
+   else
+   card->ext_csd.generic_cmd6_time = 0;
+
 out:
return err;
 }
@@ -607,7 +613,7 @@ static int mmc_select_powerclass(struct mmc_card *card,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_POWER_CLASS,
 pwrclass_val,
-0);
+card->ext_csd.generic_cmd6_time);
}

return err;
@@ -757,7 +763,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 */
if (card->ext_csd.enhanced_area_en) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-EXT_CSD_ERASE_GROUP_DEF, 1, 0);
+EXT_CSD_ERASE_GROUP_DEF, 1,
+card->ext_csd.generic_cmd6_time);

if (err && err != -EBADMSG)
goto free_card;
@@ -800,7 +807,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if ((card->ext_csd.hs_max_dtr != 0) &&
(host->caps & MMC_CAP_MMC_HIGHSPEED)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-EXT_CSD_HS_TIMING, 1, 0);
+EXT_CSD_HS_TIMING, 1,
+card->ext_csd.generic_cmd6_time);
if (err && err != -EBADMSG)
goto free_card;

@@ -880,7 +888,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_BUS_WIDTH,
 ext_csd_bits[idx][0],
-0);
+card->ext_csd.generic_cmd6_time);
if (!err) {
mmc_set_bus_width(card->host, bus_width);

@@ -911,7 +919,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_BUS_WIDTH,
 ext_csd_bits[idx][1],
-0);
+card->ext_csd.generic_cmd6_time);
}
if (err) {
printk(KERN_WARNING "%s: switch to bus width %d ddr %d "
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 5294ddf..d751ceb 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -53,6 +53,7 @@ struct mmc_ext_csd {
u8  rst_n_function;
unsigned intpart_time;  /* Units: ms */
unsigned intsa_timeout; /* Units: 100ns */
+   unsigned intgeneric_cmd6_time;  /* Units: ms */
unsigned inths_max_dtr;
unsigned intsectors;
unsigned intcard_type;
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 50af227..b26c9e4 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -304,6 +304,7 @@ struct _mmc_csd {
 #define EXT_CSD_PWR_CL_DDR_52_195  238 /* RO */
 #define EXT_CSD_PWR_CL_DDR_52_360  239 /* RO */
 #define EXT_CSD_POWER_OFF_LONG_TIME247 /* RO */
+#define EXT_CSD_GENERIC_CMD6_TIME  248 /* RO */

 /*
  * EXT_CSD field definitions
--
1.7.0.4


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


RE: [PATCH] mmc: core: Add cache control for eMMC4.5 device

2011-10-05 Thread Seungwon Jeon
Adrian Hunter wrote:
> On 08/09/11 10:29, Seungwon Jeon wrote:
> > This patch adds cache feature of eMMC4.5 Spec.
> > If device supports cache capability, host can utilize some specific
> > operations.
> >
> > Signed-off-by: Seungwon Jeon
> > ---
> > This patch is base on [PATCH v3] mmc: core: Add default timeout value
> for CMD6
> >
> >   drivers/mmc/card/block.c |   14 ++
> >   drivers/mmc/core/core.c  |   62
> ++
> >   drivers/mmc/core/mmc.c   |   23 +
> >   include/linux/mmc/card.h |2 +
> >   include/linux/mmc/core.h |2 +
> >   include/linux/mmc/host.h |3 ++
> >   include/linux/mmc/mmc.h  |3 ++
> >   7 files changed, 103 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> > index e702c61..84fa4bb 100644
> > --- a/drivers/mmc/card/block.c
> > +++ b/drivers/mmc/card/block.c
> > @@ -779,16 +779,18 @@ out:
> >   static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request
> *req)
> >   {
> > struct mmc_blk_data *md = mq->data;
> > +   struct mmc_card *card = md->queue.card;
> > +   int ret = 0;
> > +
> > +   ret = mmc_flush_cache(card);
> > +   if (ret)
> > +   ret = -EIO;
> >
> > -   /*
> > -* No-op, only service this because we need REQ_FUA for reliable
> > -* writes.
> > -*/
> > spin_lock_irq(&md->lock);
> > -   __blk_end_request_all(req, 0);
> > +   __blk_end_request_all(req, ret);
> > spin_unlock_irq(&md->lock);
> >
> > -   return 1;
> > +   return ret ? 0 : 1;
> >   }
> >
> >   /*
> > diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> > index 557856b..14c2431 100644
> > --- a/drivers/mmc/core/core.c
> > +++ b/drivers/mmc/core/core.c
> > @@ -1987,6 +1987,64 @@ int mmc_card_can_sleep(struct mmc_host *host)
> >   }
> >   EXPORT_SYMBOL(mmc_card_can_sleep);
> >
> > +/*
> > + * Flush the cache to the non-volatile storage.
> > + */
> > +int mmc_flush_cache(struct mmc_card *card)
> > +{
> > +   struct mmc_host *host = card->host;
> > +   int err = 0;
> > +
> > +   if (!(host->caps&  MMC_CAP_CACHE_CTRL))
> > +   return err;
> > +
> > +   if (mmc_card_mmc(card)&&
> > +   (card->ext_csd.cache_size>  0)&&
> > +   (card->ext_csd.cache_ctrl&  1)) {
> > +   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > +   EXT_CSD_FLUSH_CACHE, 1, 0);
> > +   if (err)
> > +   pr_err("%s: cache flush error %d\n",
> > +   mmc_hostname(card->host), err);
> > +   }
> > +
> > +   return err;
> > +}
> > +EXPORT_SYMBOL(mmc_flush_cache);
> > +
> > +/*
> > + * Turn the cache ON/OFF.
> > + * Turning the cache OFF shall trigger flushing of the data
> > + * to the non-volatile storage.
> > + */
> > +int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
> > +{
> > +   struct mmc_card *card = host->card;
> > +   int err = 0;
> > +
> > +   if (!(host->caps&  MMC_CAP_CACHE_CTRL))
> > +   return err;
> > +
> 
> This patch does not cover code paths for removable cards.
> For clarity and in case a platform does not set non-removable
> flags for eMMC, a check is needed here e.g.
> 
>   if (mmc_card_is_removable(host))
>   return 0;
> 
Is it worry about normal MMC card type and?
Then, "card->ext_csd.cache_size" is a good condition for deciding cache control.
Or even though eMMC should be non-removable type, platform does not set 
non-removable for eMMC type mistakenly?
I can't catch the meaning exactly.
Please let me know.

Thanks.
Beset regards,
Seungwon Jeon.

> > +   if (card&&  mmc_card_mmc(card)&&
> > +   (card->ext_csd.cache_size>  0)) {
> > +   enable = !!enable;
> > +
> > +   if (card->ext_csd.cache_ctrl ^ enable)
> > +   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > +   EXT_CSD_CACHE_CTRL, enable, 0);
> > +   if (err)
> > +   pr_err("%s: cache %s error %d\n",
> > +   mmc_hostname(card->host),
> > +   enable ? "on" : "off",
> > +

RE: [PATCH] mmc: core: Add cache control for eMMC4.5 device

2011-10-06 Thread Seungwon Jeon
Andrei E. Warkentin wrote:
> Hi Seungwon,
> 
> 2011/10/6 Seungwon Jeon :
> > Adrian Hunter wrote:
> >> On 08/09/11 10:29, Seungwon Jeon wrote:
> >> > This patch adds cache feature of eMMC4.5 Spec.
> >> > If device supports cache capability, host can utilize some specific
> >> > operations.
> >> >
> >> > Signed-off-by: Seungwon Jeon
> >> > ---
> 
> I don't think eMMC 4.5 is public yet, so could you elaborate on the
> volatile cache? I am
> in particular interested in how the volatile cache affects reliable
> writes (I would assume it doesn't
> affect them at all).
Right, no effect.
Data of reliable write will be written the non-volatile memory not cache 
forcedly.
> 
> A
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


RE: [PATCH] mmc: core: Add cache control for eMMC4.5 device

2011-10-06 Thread Seungwon Jeon
Adrian Hunter wrote:
> On 06/10/11 07:38, Seungwon Jeon wrote:
> > Adrian Hunter wrote:
> >> On 08/09/11 10:29, Seungwon Jeon wrote:
> >>> This patch adds cache feature of eMMC4.5 Spec.
> >>> If device supports cache capability, host can utilize some specific
> >>> operations.
> >>>
> >>> Signed-off-by: Seungwon Jeon
> >>> ---
> >>> This patch is base on [PATCH v3] mmc: core: Add default timeout value
> >> for CMD6
> >>>
> >>>drivers/mmc/card/block.c |   14 ++
> >>>drivers/mmc/core/core.c  |   62
> >> ++
> >>>drivers/mmc/core/mmc.c   |   23 +
> >>>include/linux/mmc/card.h |2 +
> >>>include/linux/mmc/core.h |2 +
> >>>include/linux/mmc/host.h |3 ++
> >>>include/linux/mmc/mmc.h  |3 ++
> >>>7 files changed, 103 insertions(+), 6 deletions(-)
> >>>
> >>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> >>> index e702c61..84fa4bb 100644
> >>> --- a/drivers/mmc/card/block.c
> >>> +++ b/drivers/mmc/card/block.c
> >>> @@ -779,16 +779,18 @@ out:
> >>>static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request
> >> *req)
> >>>{
> >>>   struct mmc_blk_data *md = mq->data;
> >>> + struct mmc_card *card = md->queue.card;
> >>> + int ret = 0;
> >>> +
> >>> + ret = mmc_flush_cache(card);
> >>> + if (ret)
> >>> + ret = -EIO;
> >>>
> >>> - /*
> >>> -  * No-op, only service this because we need REQ_FUA for reliable
> >>> -  * writes.
> >>> -  */
> >>>   spin_lock_irq(&md->lock);
> >>> - __blk_end_request_all(req, 0);
> >>> + __blk_end_request_all(req, ret);
> >>>   spin_unlock_irq(&md->lock);
> >>>
> >>> - return 1;
> >>> + return ret ? 0 : 1;
> >>>}
> >>>
> >>>/*
> >>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> >>> index 557856b..14c2431 100644
> >>> --- a/drivers/mmc/core/core.c
> >>> +++ b/drivers/mmc/core/core.c
> >>> @@ -1987,6 +1987,64 @@ int mmc_card_can_sleep(struct mmc_host *host)
> >>>}
> >>>EXPORT_SYMBOL(mmc_card_can_sleep);
> >>>
> >>> +/*
> >>> + * Flush the cache to the non-volatile storage.
> >>> + */
> >>> +int mmc_flush_cache(struct mmc_card *card)
> >>> +{
> >>> + struct mmc_host *host = card->host;
> >>> + int err = 0;
> >>> +
> >>> + if (!(host->caps&   MMC_CAP_CACHE_CTRL))
> >>> + return err;
> >>> +
> >>> + if (mmc_card_mmc(card)&&
> >>> + (card->ext_csd.cache_size>   0)&&
> >>> + (card->ext_csd.cache_ctrl&   1)) {
> >>> + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> >>> + EXT_CSD_FLUSH_CACHE, 1, 0);
> >>> + if (err)
> >>> + pr_err("%s: cache flush error %d\n",
> >>> + mmc_hostname(card->host), err);
> >>> + }
> >>> +
> >>> + return err;
> >>> +}
> >>> +EXPORT_SYMBOL(mmc_flush_cache);
> >>> +
> >>> +/*
> >>> + * Turn the cache ON/OFF.
> >>> + * Turning the cache OFF shall trigger flushing of the data
> >>> + * to the non-volatile storage.
> >>> + */
> >>> +int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
> >>> +{
> >>> + struct mmc_card *card = host->card;
> >>> + int err = 0;
> >>> +
> >>> + if (!(host->caps&   MMC_CAP_CACHE_CTRL))
> >>> + return err;
> >>> +
> >>
> >> This patch does not cover code paths for removable cards.
> >> For clarity and in case a platform does not set non-removable
> >> flags for eMMC, a check is needed here e.g.
> >>
> >>if (mmc_card_is_removable(host))
> >>return 0;
> >>
> > Is it worry about normal MMC card type and?
> > Then, "card->ext_csd.cache_size" is a good condition for deciding

[PATCH v2] mmc: core: Add cache control for eMMC4.5 device

2011-10-06 Thread Seungwon Jeon
This patch adds cache feature of eMMC4.5 Spec.
If device supports cache capability, host can utilize some specific
operations.

Signed-off-by: Seungwon Jeon 
---
v2:
Rebased to latest mmc-next branch.
Updated with comments from Adrian Hunter.
This patch is base on [PATCH v5] mmc: core: Add default timeout vaule for CMD6.

 drivers/mmc/card/block.c |   14 ++
 drivers/mmc/core/core.c  |   63 ++
 drivers/mmc/core/mmc.c   |   23 
 include/linux/mmc/card.h |2 +
 include/linux/mmc/core.h |2 +
 include/linux/mmc/host.h |3 ++
 include/linux/mmc/mmc.h  |3 ++
 7 files changed, 104 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index a527806..0e49eea 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -842,16 +842,18 @@ out:
 static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
 {
struct mmc_blk_data *md = mq->data;
+   struct mmc_card *card = md->queue.card;
+   int ret = 0;
+
+   ret = mmc_flush_cache(card);
+   if (ret)
+   ret = -EIO;

-   /*
-* No-op, only service this because we need REQ_FUA for reliable
-* writes.
-*/
spin_lock_irq(&md->lock);
-   __blk_end_request_all(req, 0);
+   __blk_end_request_all(req, ret);
spin_unlock_irq(&md->lock);

-   return 1;
+   return ret ? 0 : 1;
 }

 /*
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 9698d8a..21d94e4 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2090,6 +2090,65 @@ int mmc_card_can_sleep(struct mmc_host *host)
 }
 EXPORT_SYMBOL(mmc_card_can_sleep);

+/*
+ * Flush the cache to the non-volatile storage.
+ */
+int mmc_flush_cache(struct mmc_card *card)
+{
+   struct mmc_host *host = card->host;
+   int err = 0;
+
+   if (!(host->caps2 & MMC_CAP2_CACHE_CTRL))
+   return err;
+
+   if (mmc_card_mmc(card) &&
+   (card->ext_csd.cache_size > 0) &&
+   (card->ext_csd.cache_ctrl & 1)) {
+   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+   EXT_CSD_FLUSH_CACHE, 1, 0);
+   if (err)
+   pr_err("%s: cache flush error %d\n",
+   mmc_hostname(card->host), err);
+   }
+
+   return err;
+}
+EXPORT_SYMBOL(mmc_flush_cache);
+
+/*
+ * Turn the cache ON/OFF.
+ * Turning the cache OFF shall trigger flushing of the data
+ * to the non-volatile storage.
+ */
+int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
+{
+   struct mmc_card *card = host->card;
+   int err = 0;
+
+   if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) ||
+   mmc_card_is_removable(host))
+   return err;
+
+   if (card && mmc_card_mmc(card) &&
+   (card->ext_csd.cache_size > 0)) {
+   enable = !!enable;
+
+   if (card->ext_csd.cache_ctrl ^ enable)
+   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+   EXT_CSD_CACHE_CTRL, enable, 0);
+   if (err)
+   pr_err("%s: cache %s error %d\n",
+   mmc_hostname(card->host),
+   enable ? "on" : "off",
+   err);
+   else
+   card->ext_csd.cache_ctrl = enable;
+   }
+
+   return err;
+}
+EXPORT_SYMBOL(mmc_cache_ctrl);
+
 #ifdef CONFIG_PM

 /**
@@ -2104,6 +2163,9 @@ int mmc_suspend_host(struct mmc_host *host)
cancel_delayed_work(&host->disable);
cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
+   err = mmc_cache_ctrl(host, 0);
+   if (err)
+   goto out;

mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
@@ -2129,6 +2191,7 @@ int mmc_suspend_host(struct mmc_host *host)
if (!err && !mmc_card_keep_power(host))
mmc_power_off(host);

+out:
return err;
 }

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 4dafe45..9fa20a2 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -464,6 +464,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
else
card->ext_csd.generic_cmd6_time = 0;

+   card->ext_csd.cache_size =
+   ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 |
+   ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
+   ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
+   ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+
 out:
return err;
 }
@@ -997,6 +1003,

[PATCH v5] mmc: core: Add default timeout value for CMD6.

2011-10-15 Thread Seungwon Jeon
EXT_CSD[248] includes the default maximum timeout for CMD6.
This field is added at eMMC4.5 Spec. And it can be used for default
timeout except for some operations which don't define the timeout(i.e.
background operation, sanitize, flush cache) in eMMC4.5 Spec.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/mmc.c   |   18 +-
 include/linux/mmc/card.h |1 +
 include/linux/mmc/mmc.h  |1 +
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index c632b1f..c37b8d2 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -414,6 +414,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
else
card->erased_byte = 0x0;

+   if (card->ext_csd.rev >= 6)
+   card->ext_csd.generic_cmd6_time = 10 *
+   ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
+   else
+   card->ext_csd.generic_cmd6_time = 0;
+
 out:
return err;
 }
@@ -607,7 +613,7 @@ static int mmc_select_powerclass(struct mmc_card *card,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_POWER_CLASS,
 pwrclass_val,
-0);
+card->ext_csd.generic_cmd6_time);
}

return err;
@@ -757,7 +763,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 */
if (card->ext_csd.enhanced_area_en) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-EXT_CSD_ERASE_GROUP_DEF, 1, 0);
+EXT_CSD_ERASE_GROUP_DEF, 1,
+card->ext_csd.generic_cmd6_time);

if (err && err != -EBADMSG)
goto free_card;
@@ -800,7 +807,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if ((card->ext_csd.hs_max_dtr != 0) &&
(host->caps & MMC_CAP_MMC_HIGHSPEED)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-EXT_CSD_HS_TIMING, 1, 0);
+EXT_CSD_HS_TIMING, 1,
+card->ext_csd.generic_cmd6_time);
if (err && err != -EBADMSG)
goto free_card;

@@ -880,7 +888,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_BUS_WIDTH,
 ext_csd_bits[idx][0],
-0);
+card->ext_csd.generic_cmd6_time);
if (!err) {
mmc_set_bus_width(card->host, bus_width);

@@ -911,7 +919,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_BUS_WIDTH,
 ext_csd_bits[idx][1],
-0);
+card->ext_csd.generic_cmd6_time);
}
if (err) {
printk(KERN_WARNING "%s: switch to bus width %d ddr %d "
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 5294ddf..d751ceb 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -53,6 +53,7 @@ struct mmc_ext_csd {
u8  rst_n_function;
unsigned intpart_time;  /* Units: ms */
unsigned intsa_timeout; /* Units: 100ns */
+   unsigned intgeneric_cmd6_time;  /* Units: ms */
unsigned inths_max_dtr;
unsigned intsectors;
unsigned intcard_type;
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 50af227..b26c9e4 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -304,6 +304,7 @@ struct _mmc_csd {
 #define EXT_CSD_PWR_CL_DDR_52_195  238 /* RO */
 #define EXT_CSD_PWR_CL_DDR_52_360  239 /* RO */
 #define EXT_CSD_POWER_OFF_LONG_TIME247 /* RO */
+#define EXT_CSD_GENERIC_CMD6_TIME  248 /* RO */

 /*
  * EXT_CSD field definitions
--
1.7.0.4

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


RE: [PATCH v5] mmc: core: Add default timeout value for CMD6.

2011-10-16 Thread Seungwon Jeon
This mail is  a duplicate from our security machine.
V5 of related patch has already submitted.
Please ignore this resending.
I think that it was unfortunate.

Seungwon Jeon.

> EXT_CSD[248] includes the default maximum timeout for CMD6.
> This field is added at eMMC4.5 Spec. And it can be used for default
> timeout except for some operations which don't define the timeout(i.e.
> background operation, sanitize, flush cache) in eMMC4.5 Spec.
> 
> Signed-off-by: Seungwon Jeon 
> ---
>  drivers/mmc/core/mmc.c   |   18 +-
>  include/linux/mmc/card.h |1 +
>  include/linux/mmc/mmc.h  |1 +
>  3 files changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index c632b1f..c37b8d2 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -414,6 +414,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8
> *ext_csd)
>   else
>   card->erased_byte = 0x0;
> 
> + if (card->ext_csd.rev >= 6)
> + card->ext_csd.generic_cmd6_time = 10 *
> + ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
> + else
> + card->ext_csd.generic_cmd6_time = 0;
> +
>  out:
>   return err;
>  }
> @@ -607,7 +613,7 @@ static int mmc_select_powerclass(struct mmc_card *card,
>   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>EXT_CSD_POWER_CLASS,
>pwrclass_val,
> -  0);
> +  card->ext_csd.generic_cmd6_time);
>   }
> 
>   return err;
> @@ -757,7 +763,8 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
>*/
>   if (card->ext_csd.enhanced_area_en) {
>   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> -  EXT_CSD_ERASE_GROUP_DEF, 1, 0);
> +  EXT_CSD_ERASE_GROUP_DEF, 1,
> +  card->ext_csd.generic_cmd6_time);
> 
>   if (err && err != -EBADMSG)
>   goto free_card;
> @@ -800,7 +807,8 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
>   if ((card->ext_csd.hs_max_dtr != 0) &&
>   (host->caps & MMC_CAP_MMC_HIGHSPEED)) {
>   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> -  EXT_CSD_HS_TIMING, 1, 0);
> +  EXT_CSD_HS_TIMING, 1,
> +  card->ext_csd.generic_cmd6_time);
>   if (err && err != -EBADMSG)
>   goto free_card;
> 
> @@ -880,7 +888,7 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
>   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>EXT_CSD_BUS_WIDTH,
>ext_csd_bits[idx][0],
> -  0);
> +  card->ext_csd.generic_cmd6_time);
>   if (!err) {
>   mmc_set_bus_width(card->host, bus_width);
> 
> @@ -911,7 +919,7 @@ static int mmc_init_card(struct mmc_host *host, u32
> ocr,
>   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>EXT_CSD_BUS_WIDTH,
>ext_csd_bits[idx][1],
> -  0);
> +  card->ext_csd.generic_cmd6_time);
>   }
>   if (err) {
>   printk(KERN_WARNING "%s: switch to bus width %d ddr %d
> "
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index 5294ddf..d751ceb 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -53,6 +53,7 @@ struct mmc_ext_csd {
>   u8  rst_n_function;
>   unsigned intpart_time;  /* Units: ms */
>   unsigned intsa_timeout; /* Units: 100ns */
> + unsigned intgeneric_cmd6_time;  /* Units: ms */
>   unsigned inths_max_dtr;
>   unsigned intsectors;
>   unsigned intcard_type;
> diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
> index 50af227..b26c9e4 100644
> --- a/include/linux/mmc/mmc.h
> +++ b/include/linux/mmc/mmc.h
> @@ -304,6 +304,7 @@ struct _mmc_csd {
>  #define EXT_CSD_PWR_CL_DDR_52_195238 /* RO */
>  #define EXT_CSD_PWR_CL_DDR_52_360239 /* RO */
>  #define EXT_CSD_POWER_OFF_LONG_TIME  247 /*

RE: [PATCH V8] mmc: core: Add Power Off Notify Feature eMMC 4.5

2011-10-17 Thread Seungwon Jeon
Base code of V8 may be mixed.
Please check below for next resending. It seems like unrelated.

#define MMC_CAP2_CACHE_CTRL (1 << 1)
#define EXT_CSD_FLUSH_CACHE 32

Best regards,
Seungwon Jeon.

Girish K S wrote:
> This patch adds the support for power off notify feature, available in
> eMMC 4.5 devices. If the the host has support for this feature, then the
> mmc core will notify it to the device by setting the
> POWER_OFF_NOTIFICATION
> byte in the extended csd register with a value 1(POWER_ON).
> 
> For suspend mode short timeout is used, whereas for the normal poweroff
> long
> timeout is used.
> cc: Chris Ball 
> Signed-off-by: Girish K S 
> Signed-off-by: Jaehoon Chung 
> ---
> Changes in V8:
>   Updated with review comments of Chris Ball and rebased to
>   chris-mmc/mmc-next branch.
> Changes in V7:
>   Rebased to chris-mmc/mmc-next branch. merged to patches
>   to single patch.
> Changes in V6:
>   Fixes checkpatch errors. The patches are generated after
>   rebasing to chris's mmc-next branch.
> Changes in V5:
>   This patch version fixes the problem with power off
>   notify function, when called for the first time and
>   card is not yet initialised.
> Changes in V4:
>   Updated with review comments of Jeon
> Changes in V2:
>   Adds poweroff notification handling in suspend/normal.
> 
>  drivers/mmc/core/core.c  |   36 
>  drivers/mmc/core/mmc.c   |   23 +--
>  drivers/mmc/host/sdhci.c |9 +
>  include/linux/mmc/card.h |6 ++
>  include/linux/mmc/host.h |6 ++
>  include/linux/mmc/mmc.h  |8 
>  6 files changed, 86 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 61d7730..db368b2 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -1212,11 +1212,45 @@ static void mmc_power_up(struct mmc_host *host)
> 
>  void mmc_power_off(struct mmc_host *host)
>  {
> + struct mmc_card *card;
> + unsigned int notify_type;
> + unsigned int timeout;
> + int err;
> +
> + BUG_ON(!host);
> +
>   mmc_host_clk_hold(host);
> 
> + card = host->card;
>   host->ios.clock = 0;
>   host->ios.vdd = 0;
> 
> + if (card != NULL && mmc_card_mmc(card) &&
> + (card->poweroff_notify_state == MMC_POWERED_ON)) {
> +
> + if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
> + notify_type = EXT_CSD_POWER_OFF_SHORT;
> + timeout = card->ext_csd.generic_cmd6_time;
> + card->poweroff_notify_state = MMC_POWEROFF_SHORT;
> + } else {
> + notify_type = EXT_CSD_POWER_OFF_LONG;
> + timeout = card->ext_csd.power_off_longtime;
> + card->poweroff_notify_state = MMC_POWEROFF_LONG;
> + }
> +
> + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> +  EXT_CSD_POWER_OFF_NOTIFICATION,
> +  notify_type, timeout);
> +
> + if (err && err != -EBADMSG)
> + pr_err("Device failed to respond within %d poweroff "
> +"time. Forcefully powering down the device\n",
> +timeout);
> +
> + /* Set the card state to no notification after the poweroff
> */
> + card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
> + }
> +
>   /*
>* Reset ocr mask to be the highest possible voltage supported for
>* this mmc host. This value will be used at next power up.
> @@ -2208,6 +2242,7 @@ int mmc_pm_notify(struct notifier_block
> *notify_block,
> 
>   spin_lock_irqsave(&host->lock, flags);
>   host->rescan_disable = 1;
> + host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
>   spin_unlock_irqrestore(&host->lock, flags);
>   cancel_delayed_work_sync(&host->detect);
> 
> @@ -2231,6 +2266,7 @@ int mmc_pm_notify(struct notifier_block
> *notify_block,
> 
>   spin_lock_irqsave(&host->lock, flags);
>   host->rescan_disable = 0;
> + host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
>   spin_unlock_irqrestore(&host->lock, flags);
>   mmc_detect_change(host, 0);
> 
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index 4e869d3..f8ea938 100644
&g

[PATCH] mmc: core: Modify the timeout value for writing power class

2011-10-17 Thread Seungwon Jeon
This patch will apply the generic CMD6 timeout to switch command
for power class.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/mmc.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index f8ea938..d19440d 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -659,7 +659,7 @@ static int mmc_select_powerclass(struct mmc_card *card,
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 EXT_CSD_POWER_CLASS,
 pwrclass_val,
-0);
+card->ext_csd.generic_cmd6_time);
}

return err;
--
1.7.0.4


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


[PATCH] mmc: core: Separate the timeout value for cache-ctrl

2011-10-24 Thread Seungwon Jeon
Turning the cache off implies flushing cache which doesn't define
maximum timeout unlike cache-on. This patch will apply the generic
CMD6 timeout only for cache-on. Additionally the kernel message is
added for checking failure case of cache-on.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/core.c |   22 +-
 drivers/mmc/core/mmc.c  |   10 --
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 5278ffb..65b5643 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2248,6 +2248,7 @@ EXPORT_SYMBOL(mmc_flush_cache);
 int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
 {
struct mmc_card *card = host->card;
+   unsigned int timeout;
int err = 0;

if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) ||
@@ -2258,16 +2259,19 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
(card->ext_csd.cache_size > 0)) {
enable = !!enable;

-   if (card->ext_csd.cache_ctrl ^ enable)
+   if (card->ext_csd.cache_ctrl ^ enable) {
+   timeout = enable ? card->ext_csd.generic_cmd6_time : 0;
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-   EXT_CSD_CACHE_CTRL, enable, 0);
-   if (err)
-   pr_err("%s: cache %s error %d\n",
-   mmc_hostname(card->host),
-   enable ? "on" : "off",
-   err);
-   else
-   card->ext_csd.cache_ctrl = enable;
+   EXT_CSD_CACHE_CTRL, enable, timeout);
+
+   if (err)
+   pr_err("%s: cache %s error %d\n",
+   mmc_hostname(card->host),
+   enable ? "on" : "off",
+   err);
+   else
+   card->ext_csd.cache_ctrl = enable;
+   }
}

return err;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index fb5bf01..6354eb3 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1064,14 +1064,20 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if ((host->caps2 & MMC_CAP2_CACHE_CTRL) &&
card->ext_csd.cache_size > 0) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-   EXT_CSD_CACHE_CTRL, 1, 0);
+   EXT_CSD_CACHE_CTRL, 1,
+   card->ext_csd.generic_cmd6_time);
if (err && err != -EBADMSG)
goto free_card;

/*
 * Only if no error, cache is turned on successfully.
 */
-   card->ext_csd.cache_ctrl = err ? 0 : 1;
+   if (err) {
+   pr_warning("%s: Cache is supported, but enabling 
failed\n",
+   mmc_hostname(card->host));
+   err = 0;
+   } else
+   card->ext_csd.cache_ctrl = 1;
}

if (!oldcard)
--
1.7.0.4


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


[PATCH] mmc: core: Assemble the codes of related to eMMC4.5

2011-10-24 Thread Seungwon Jeon
Code cleanup. The codes of related to eMMC4.5 are scattered.
This patch removes a duplicate if-statement and assembles all.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/mmc.c |   20 +---
 1 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index fb5bf01..3627044 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -467,29 +467,27 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION];
}

-   /* eMMC v4.5 or later */
-   if (card->ext_csd.rev >= 6)
-   card->ext_csd.feature_support |= MMC_DISCARD_FEATURE;
-
card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];
if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
card->erased_byte = 0xFF;
else
card->erased_byte = 0x0;

+   /* eMMC v4.5 or later */
if (card->ext_csd.rev >= 6) {
+   card->ext_csd.feature_support |= MMC_DISCARD_FEATURE;
+
card->ext_csd.generic_cmd6_time = 10 *
ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
card->ext_csd.power_off_longtime = 10 *
ext_csd[EXT_CSD_POWER_OFF_LONG_TIME];
-   } else
-   card->ext_csd.generic_cmd6_time = 0;

-   card->ext_csd.cache_size =
-   ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 |
-   ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
-   ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
-   ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+   card->ext_csd.cache_size =
+   ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 |
+   ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
+   ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
+   ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+   }

 out:
return err;
--
1.7.0.4


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


RE: [PATCH] mmc: core: Separate the timeout value for cache-ctrl

2011-10-24 Thread Seungwon Jeon
Girish K S wrote:
> On 24 October 2011 15:40, Seungwon Jeon  wrote:
> > Turning the cache off implies flushing cache which doesn't define
> > maximum timeout unlike cache-on. This patch will apply the generic
> > CMD6 timeout only for cache-on. Additionally the kernel message is
> > added for checking failure case of cache-on.
> >
> > Signed-off-by: Seungwon Jeon 
> > ---
> >  drivers/mmc/core/core.c |   22 +-
> >  drivers/mmc/core/mmc.c  |   10 --
> >  2 files changed, 21 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> > index 5278ffb..65b5643 100644
> > --- a/drivers/mmc/core/core.c
> > +++ b/drivers/mmc/core/core.c
> > @@ -2248,6 +2248,7 @@ EXPORT_SYMBOL(mmc_flush_cache);
> >  int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
> >  {
> >        struct mmc_card *card = host->card;
> > +       unsigned int timeout;
> >        int err = 0;
> >
> >        if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) ||
> > @@ -2258,16 +2259,19 @@ int mmc_cache_ctrl(struct mmc_host *host, u8
> enable)
> >                        (card->ext_csd.cache_size > 0)) {
> >                enable = !!enable;
> >
> > -               if (card->ext_csd.cache_ctrl ^ enable)
> > +               if (card->ext_csd.cache_ctrl ^ enable) {
> > +                       timeout = enable ?
card->ext_csd.generic_cmd6_time :
> 0;
> >                        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > -                                       EXT_CSD_CACHE_CTRL, enable, 0);
> Here timeout value used is 0. If it has to be 0 then why should you check
> timeout = enable ? card->ext_csd.generic_cmd6_time : 0;
> I think it should be card->ext_csd.generic_cmd6_time instead of 0
Upper line you pointed was removed. Could check '-', please?
> > -               if (err)
> > -                       pr_err("%s: cache %s error %d\n",
> > -                                       mmc_hostname(card->host),
> > -                                       enable ? "on" : "off",
> > -                                       err);
> > -               else
> > -                       card->ext_csd.cache_ctrl = enable;
> > +                                       EXT_CSD_CACHE_CTRL, enable,
timeout);
Here is modified line.

Beset regards,
Seungwon Jeon.
> > +
> > +                       if (err)
> > +                               pr_err("%s: cache %s error %d\n",
> > +                                              
mmc_hostname(card->host),
> > +                                               enable ? "on" : "off",
> > +                                               err);
> > +                       else
> > +                               card->ext_csd.cache_ctrl = enable;
> > +               }
> >        }
> >
> >        return err;
> > diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> > index fb5bf01..6354eb3 100644
> > --- a/drivers/mmc/core/mmc.c
> > +++ b/drivers/mmc/core/mmc.c
> > @@ -1064,14 +1064,20 @@ static int mmc_init_card(struct mmc_host *host,
> u32 ocr,
> >        if ((host->caps2 & MMC_CAP2_CACHE_CTRL) &&
> >                        card->ext_csd.cache_size > 0) {
> >                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> > -                               EXT_CSD_CACHE_CTRL, 1, 0);
> > +                               EXT_CSD_CACHE_CTRL, 1,
> > +                               card->ext_csd.generic_cmd6_time);
> >                if (err && err != -EBADMSG)
> >                        goto free_card;
> >
> >                /*
> >                 * Only if no error, cache is turned on successfully.
> >                 */
> > -               card->ext_csd.cache_ctrl = err ? 0 : 1;
> > +               if (err) {
> > +                       pr_warning("%s: Cache is supported, but enabling
> failed\n",
> > +                                       mmc_hostname(card->host));
> > +                       err = 0;
> > +               } else
> > +                       card->ext_csd.cache_ctrl = 1;
> >        }
> >
> >        if (!oldcard)
> > --
> > 1.7.0.4
> >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> > the body of a message to majord...@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >

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


RE: [PATCH] mmc: core: Assemble the codes of related to eMMC4.5

2011-10-24 Thread Seungwon Jeon
Chris Ball wrote:
> Hi Seungwon,
> 
> On Mon, Oct 24 2011, Seungwon Jeon wrote:
> > Code cleanup. The codes of related to eMMC4.5 are scattered.
> > This patch removes a duplicate if-statement and assembles all.
> >
> > Signed-off-by: Seungwon Jeon 
> > ---
> >  drivers/mmc/core/mmc.c |   20 +---
> >  1 files changed, 9 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> > index fb5bf01..3627044 100644
> > --- a/drivers/mmc/core/mmc.c
> > +++ b/drivers/mmc/core/mmc.c
> > @@ -467,29 +467,27 @@ static int mmc_read_ext_csd(struct mmc_card *card,
> u8 *ext_csd)
> > card->ext_csd.rst_n_function =
> ext_csd[EXT_CSD_RST_N_FUNCTION];
> > }
> >
> > -   /* eMMC v4.5 or later */
> > -   if (card->ext_csd.rev >= 6)
> > -   card->ext_csd.feature_support |= MMC_DISCARD_FEATURE;
> > -
> > card->ext_csd.raw_erased_mem_count =
> ext_csd[EXT_CSD_ERASED_MEM_CONT];
> > if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
> > card->erased_byte = 0xFF;
> > else
> > card->erased_byte = 0x0;
> >
> > +   /* eMMC v4.5 or later */
> > if (card->ext_csd.rev >= 6) {
> > +   card->ext_csd.feature_support |= MMC_DISCARD_FEATURE;
> > +
> > card->ext_csd.generic_cmd6_time = 10 *
> > ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
> > card->ext_csd.power_off_longtime = 10 *
> > ext_csd[EXT_CSD_POWER_OFF_LONG_TIME];
> > -   } else
> > -   card->ext_csd.generic_cmd6_time = 0;
> 
> Your patch removes this line completely.  Why is that?  You should
> explain it in the commit message.
Sure, I will.
Removed line is just for explicit initialization considering previous
version
even though generic_cmd6_time is zeroed at card init-time.
So it seems be unnecessary.

Best regards,
Seungwon Jeon.

> 
> >
> > -   card->ext_csd.cache_size =
> > -   ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 |
> > -   ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
> > -   ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
> > -   ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
> > +   card->ext_csd.cache_size =
> > +   ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 |
> > +   ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
> > +   ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
> > +   ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
> > +   }
> >
> >  out:
> > return err;
> 
> The rest looks good, thanks,
> 
> - Chris.
> --
> Chris Ball  <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


[PATCH RESEND] mmc: core: Assemble the codes of related to eMMC4.5

2011-10-24 Thread Seungwon Jeon
Code cleanup. The codes of related to eMMC4.5 are scattered.
This patch removes one if-statement and assembles all. And it also
removes variable initialization below else-statement. It is obvious
for previous version but seems unnecessary. All members of card structure
are already set to zero at card-init.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/mmc.c |   20 +---
 1 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 6354eb3..6354bac 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -467,29 +467,27 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION];
}

-   /* eMMC v4.5 or later */
-   if (card->ext_csd.rev >= 6)
-   card->ext_csd.feature_support |= MMC_DISCARD_FEATURE;
-
card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];
if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
card->erased_byte = 0xFF;
else
card->erased_byte = 0x0;

+   /* eMMC v4.5 or later */
if (card->ext_csd.rev >= 6) {
+   card->ext_csd.feature_support |= MMC_DISCARD_FEATURE;
+
card->ext_csd.generic_cmd6_time = 10 *
ext_csd[EXT_CSD_GENERIC_CMD6_TIME];
card->ext_csd.power_off_longtime = 10 *
ext_csd[EXT_CSD_POWER_OFF_LONG_TIME];
-   } else
-   card->ext_csd.generic_cmd6_time = 0;

-   card->ext_csd.cache_size =
-   ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 |
-   ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
-   ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
-   ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+   card->ext_csd.cache_size =
+   ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 |
+   ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
+   ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
+   ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+   }

 out:
return err;
--
1.7.0.4


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


[PATCH] mmc: core: Add packed command for eMMC4.5 device

2011-10-27 Thread Seungwon Jeon
This patch supports packed command feature of eMMC4.5 Spec.
Several reads(or writes) can be grouped in packed command
and all data of the individual commands can be sent in one
transfer on the bus.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/card/block.c |  349 --
 drivers/mmc/card/queue.c |   48 ++-
 drivers/mmc/card/queue.h |   12 ++
 drivers/mmc/core/mmc.c   |   20 +++
 include/linux/mmc/card.h |3 +
 include/linux/mmc/host.h |1 +
 include/linux/mmc/mmc.h  |   15 ++
 7 files changed, 434 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 4fd5723..0258a81 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -45,6 +45,7 @@
 #include 

 #include "queue.h"
+#include "../core/mmc_ops.h"

 MODULE_ALIAS("mmc:block");
 #ifdef MODULE_PARAM_PREFIX
@@ -59,6 +60,10 @@ MODULE_ALIAS("mmc:block");
 #define INAND_CMD38_ARG_SECTRIM1 0x81
 #define INAND_CMD38_ARG_SECTRIM2 0x88

+#define mmc_req_rel_wr(req)(((req->cmd_flags & REQ_FUA) || \
+   (req->cmd_flags & REQ_META)) && \
+   (rq_data_dir(req) == WRITE))
+
 static DEFINE_MUTEX(block_mutex);

 /*
@@ -943,7 +948,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
 * kind.  If it was a write, we may have transitioned to
 * program mode, which we have to wait for it to complete.
 */
-   if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
+   if ((!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) ||
+   (mq_mrq->packed_cmd == MMC_PACKED_WR_HDR)) {
u32 status;
do {
int err = get_card_status(card, &status, 5);
@@ -980,12 +986,67 @@ static int mmc_blk_err_check(struct mmc_card *card,
if (!brq->data.bytes_xfered)
return MMC_BLK_RETRY;

+   if (mq_mrq->packed_cmd != MMC_PACKED_NONE) {
+   if (unlikely(brq->data.blocks << 9 != brq->data.bytes_xfered))
+   return MMC_BLK_PARTIAL;
+   else
+   return MMC_BLK_SUCCESS;
+   }
+
if (blk_rq_bytes(req) != brq->data.bytes_xfered)
return MMC_BLK_PARTIAL;

return MMC_BLK_SUCCESS;
 }

+static int mmc_blk_packed_err_check(struct mmc_card *card,
+struct mmc_async_req *areq)
+{
+   struct mmc_queue_req *mq_mrq = container_of(areq, struct mmc_queue_req,
+   mmc_active);
+   int err, check, status;
+   u8 ext_csd[512];
+
+   check = mmc_blk_err_check(card, areq);
+
+   if (check == MMC_BLK_SUCCESS)
+   return check;
+
+   if (check == MMC_BLK_PARTIAL) {
+   err = get_card_status(card, &status, 0);
+   if (err)
+   return MMC_BLK_ABORT;
+
+   if (status & R1_EXP_EVENT) {
+   err = mmc_send_ext_csd(card, ext_csd);
+   if (err)
+   return MMC_BLK_ABORT;
+
+   if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS + 0] &
+   EXT_CSD_PACKED_FAILURE) &&
+   (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
+EXT_CSD_PACKED_GENERIC_ERROR)) {
+   if (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
+   EXT_CSD_PACKED_INDEXED_ERROR) {
+   /* Make be 0-based */
+   mq_mrq->packed_fail_idx =
+   
ext_csd[EXT_CSD_PACKED_FAILURE_INDEX] - 1;
+   return MMC_BLK_PARTIAL;
+   } else {
+   return MMC_BLK_RETRY;
+   }
+   }
+   } else {
+   return MMC_BLK_RETRY;
+   }
+   }
+
+   if (check != MMC_BLK_ABORT)
+   return MMC_BLK_RETRY;
+   else
+   return MMC_BLK_ABORT;
+}
+
 static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
   struct mmc_card *card,
   int disable_multi,
@@ -1126,6 +1187,207 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
*mqrq,
mmc_queue_bounce_pre(mqrq);
 }

+static u8 mmc_blk_chk_packable(struct mmc_queue *mq, struct request *req)
+{
+   struct request_queue *q = mq->queue;
+   struct mmc_card *card = mq->card;
+   struct request *cur = req, *next = NULL;
+   struct mmc_blk_data *md = mq->data;
+   bool en_rel_wr = card->ext_csd.

RE: [PATCH] mmc: core: Add packed command for eMMC4.5 device

2011-10-27 Thread Seungwon Jeon
S, Venkatraman   wrote: 
> On Thu, Oct 27, 2011 at 4:24 PM, Seungwon Jeon  wrote:
> > This patch supports packed command feature of eMMC4.5 Spec.
> > Several reads(or writes) can be grouped in packed command
> > and all data of the individual commands can be sent in one
> > transfer on the bus.
> >
> > Signed-off-by: Seungwon Jeon 
> > ---
> >  drivers/mmc/card/block.c |  349 
> > --
> >  drivers/mmc/card/queue.c |   48 ++-
> >  drivers/mmc/card/queue.h |   12 ++
> >  drivers/mmc/core/mmc.c   |   20 +++
> >  include/linux/mmc/card.h |    3 +
> >  include/linux/mmc/host.h |    1 +
> >  include/linux/mmc/mmc.h  |   15 ++
> >  7 files changed, 434 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> > index 4fd5723..0258a81 100644
> > --- a/drivers/mmc/card/block.c
> > +++ b/drivers/mmc/card/block.c
> > @@ -45,6 +45,7 @@
> >  #include 
> >
> >  #include "queue.h"
> > +#include "../core/mmc_ops.h"
> 
> I don't think this is the right way to include files.  The core
> directory should be in the include path already.
Ok, I'll make be well-formed.
> 
> >
> >  MODULE_ALIAS("mmc:block");
> >  #ifdef MODULE_PARAM_PREFIX
> > @@ -59,6 +60,10 @@ MODULE_ALIAS("mmc:block");
> >  #define INAND_CMD38_ARG_SECTRIM1 0x81
> >  #define INAND_CMD38_ARG_SECTRIM2 0x88
> >
> > +#define mmc_req_rel_wr(req)    (((req->cmd_flags & REQ_FUA) || \
> > +                       (req->cmd_flags & REQ_META)) && \
> > +                       (rq_data_dir(req) == WRITE))
> > +
> >  static DEFINE_MUTEX(block_mutex);
> >
> >  /*
> > @@ -943,7 +948,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
> >         * kind.  If it was a write, we may have transitioned to
> >         * program mode, which we have to wait for it to complete.
> >         */
> > -       if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
> > +       if ((!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) ||
> > +                       (mq_mrq->packed_cmd == MMC_PACKED_WR_HDR)) {
> >                u32 status;
> >                do {
> >                        int err = get_card_status(card, &status, 5);
> > @@ -980,12 +986,67 @@ static int mmc_blk_err_check(struct mmc_card *card,
> >        if (!brq->data.bytes_xfered)
> >                return MMC_BLK_RETRY;
> >
> > +       if (mq_mrq->packed_cmd != MMC_PACKED_NONE) {
> > +               if (unlikely(brq->data.blocks << 9 != 
> > brq->data.bytes_xfered))
> > +                       return MMC_BLK_PARTIAL;
> > +               else
> > +                       return MMC_BLK_SUCCESS;
> > +       }
> > +
> >        if (blk_rq_bytes(req) != brq->data.bytes_xfered)
> >                return MMC_BLK_PARTIAL;
> >
> >        return MMC_BLK_SUCCESS;
> >  }
> >
> > +static int mmc_blk_packed_err_check(struct mmc_card *card,
> > +                            struct mmc_async_req *areq)
> > +{
> > +       struct mmc_queue_req *mq_mrq = container_of(areq, struct 
> > mmc_queue_req,
> > +                                                   mmc_active);
> > +       int err, check, status;
> > +       u8 ext_csd[512];
> > +
> > +       check = mmc_blk_err_check(card, areq);
> > +
> > +       if (check == MMC_BLK_SUCCESS)
> > +               return check;
> > +
> > +       if (check == MMC_BLK_PARTIAL) {
> > +               err = get_card_status(card, &status, 0);
> > +               if (err)
> > +                       return MMC_BLK_ABORT;
> > +
> > +               if (status & R1_EXP_EVENT) {
> > +                       err = mmc_send_ext_csd(card, ext_csd);
> > +                       if (err)
> > +                               return MMC_BLK_ABORT;
> > +
> > +                       if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS + 0] &
> > +                                               EXT_CSD_PACKED_FAILURE) &&
> > +                                       (ext_csd[EXT_CSD_PACKED_CMD_STATUS] 
> > &
> > +                                        EXT_CSD_PACKED_GENERIC_ERROR)) {
> > +                               if (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
> > +                                               
> > EXT_CSD_PACKED_INDEXED_ERROR) {
> > +                 

[PATCH 0/2] mmc: core: Support packed command feature of eMMC4.5

2011-11-02 Thread Seungwon Jeon
This patch-set adds support of packed command feature
for eMMC4.5 devices.

Seungwon Jeon (2):
mmc: core: Add packed command feature of eMMC4.5
mmc: core: Support packed command for eMMC4.5 device

 drivers/mmc/card/block.c |  355 --
 drivers/mmc/card/queue.c |   48 ++-
 drivers/mmc/card/queue.h |   12 ++
 drivers/mmc/core/mmc.c   |   22 ++
 include/linux/mmc/core.h |3 +
 include/linux/mmc/card.h |3 +++
 include/linux/mmc/host.h |1 +
 include/linux/mmc/mmc.h  |   15 +++
 8 files changed, 445 insertions(+), 14 deletions(-)
--
1.7.2.3

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


[PATCH 1/2] mmc: core: Add packed command feature of eMMC4.5

2011-11-02 Thread Seungwon Jeon
This patch adds packed command feature of eMMC4.5.
The maximum number for packing read(or write) is offered
and exception event relevant to packed command which is
used for error handling is enabled. If host wants to use
this feature, MMC_CAP2_PACKED_CMD should be set.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/mmc.c   |   22 ++
 include/linux/mmc/card.h |3 +++
 include/linux/mmc/host.h |1 +
 include/linux/mmc/mmc.h  |   15 +++
 4 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 3627044..bf4fa6e 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -487,6 +487,9 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+
+   card->ext_csd.max_packed_writes = 
ext_csd[EXT_CSD_MAX_PACKED_WRITES];
+   card->ext_csd.max_packed_reads = 
ext_csd[EXT_CSD_MAX_PACKED_READS];
}

 out:
@@ -1072,6 +1075,25 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
card->ext_csd.cache_ctrl = err ? 0 : 1;
}

+   if ((host->caps2 & MMC_CAP2_PACKED_CMD) &&
+   (card->ext_csd.max_packed_writes > 0) &&
+   (card->ext_csd.max_packed_reads > 0)) {
+   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+   EXT_CSD_EXP_EVENTS_CTRL,
+   EXT_CSD_PACKED_EVENT_EN,
+   card->ext_csd.generic_cmd6_time);
+   if (err && err != -EBADMSG)
+   goto free_card;
+   if (err) {
+   pr_warning("%s: Enabling packed event failed\n",
+   mmc_hostname(card->host));
+   card->ext_csd.packed_event_en = 0;
+   err = 0;
+   } else {
+   card->ext_csd.packed_event_en = 1;
+   }
+   }
+
if (!oldcard)
host->card = card;

diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 415f2db..70ea3d6 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -52,6 +52,9 @@ struct mmc_ext_csd {
u8  part_config;
u8  cache_ctrl;
u8  rst_n_function;
+   u8  max_packed_writes;
+   u8  max_packed_reads;
+   u8  packed_event_en;
unsigned intpart_time;  /* Units: ms */
unsigned intsa_timeout; /* Units: 100ns */
unsigned intgeneric_cmd6_time;  /* Units: 10ms */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index a3ac9c4..d2e4210 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -242,6 +242,7 @@ struct mmc_host {
 #define MMC_CAP2_CACHE_CTRL(1 << 1)/* Allow cache control */
 #define MMC_CAP2_POWEROFF_NOTIFY (1 << 2)  /* Notify poweroff supported */
 #define MMC_CAP2_NO_MULTI_READ (1 << 3)/* Multiblock reads don't work 
*/
+#define MMC_CAP2_PACKED_CMD(1 << 4)/* Allow packed command */

mmc_pm_flag_t   pm_caps;/* supported pm features */
unsigned intpower_notify_type;
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 0e71356..1b94c4f 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -138,6 +138,7 @@ static inline bool mmc_op_multi(u32 opcode)
 #define R1_CURRENT_STATE(x)((x & 0x1E00) >> 9) /* sx, b (4 bits) */
 #define R1_READY_FOR_DATA  (1 << 8)/* sx, a */
 #define R1_SWITCH_ERROR(1 << 7)/* sx, c */
+#define R1_EXP_EVENT   (1 << 6)/* sr, a */
 #define R1_APP_CMD (1 << 5)/* sr, c */

 #define R1_STATE_IDLE  0
@@ -273,6 +274,10 @@ struct _mmc_csd {
 #define EXT_CSD_FLUSH_CACHE32  /* W */
 #define EXT_CSD_CACHE_CTRL 33  /* R/W */
 #define EXT_CSD_POWER_OFF_NOTIFICATION 34  /* R/W */
+#define EXT_CSD_PACKED_FAILURE_INDEX   35  /* RO */
+#define EXT_CSD_PACKED_CMD_STATUS  36  /* RO */
+#define EXT_CSD_EXP_EVENTS_STATUS  54  /* RO, 2 bytes */
+#define EXT_CSD_EXP_EVENTS_CTRL56  /* R/W, 2 bytes */
 #define EXT_CSD_GP_SIZE_MULT   143 /* R/W */
 #define EXT_CSD_PARTITION_ATTRIBUTE156 /* R/W */
 #define EXT_CSD_PARTITION_SUPPORT  160 /* RO */
@@ -313,6 +318,8 @@ struct _mmc_csd {
 #define EXT_CSD_POWER_OFF_LON

[PATCH 2/2] mmc: core: Support packed command for eMMC4.5 device

2011-11-02 Thread Seungwon Jeon
This patch supports packed command of eMMC4.5 device.
Several reads(or writes) can be grouped in packed command
and all data of the individual commands can be sent in a
single transfer on the bus.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/card/block.c |  355 --
 drivers/mmc/card/queue.c |   48 ++-
 drivers/mmc/card/queue.h |   12 ++
 include/linux/mmc/core.h |3 +
 4 files changed, 404 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index a1cb21f..6c49656 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -59,6 +59,13 @@ MODULE_ALIAS("mmc:block");
 #define INAND_CMD38_ARG_SECTRIM1 0x81
 #define INAND_CMD38_ARG_SECTRIM2 0x88

+#define mmc_req_rel_wr(req)(((req->cmd_flags & REQ_FUA) || \
+   (req->cmd_flags & REQ_META)) && \
+   (rq_data_dir(req) == WRITE))
+#define PACKED_CMD_VER 0x01
+#define PACKED_CMD_RD  0x01
+#define PACKED_CMD_WR  0x02
+
 static DEFINE_MUTEX(block_mutex);

 /*
@@ -943,7 +950,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
 * kind.  If it was a write, we may have transitioned to
 * program mode, which we have to wait for it to complete.
 */
-   if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
+   if ((!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) ||
+   (mq_mrq->packed_cmd == MMC_PACKED_WR_HDR)) {
u32 status;
do {
int err = get_card_status(card, &status, 5);
@@ -980,12 +988,67 @@ static int mmc_blk_err_check(struct mmc_card *card,
if (!brq->data.bytes_xfered)
return MMC_BLK_RETRY;

+   if (mq_mrq->packed_cmd != MMC_PACKED_NONE) {
+   if (unlikely(brq->data.blocks << 9 != brq->data.bytes_xfered))
+   return MMC_BLK_PARTIAL;
+   else
+   return MMC_BLK_SUCCESS;
+   }
+
if (blk_rq_bytes(req) != brq->data.bytes_xfered)
return MMC_BLK_PARTIAL;

return MMC_BLK_SUCCESS;
 }

+static int mmc_blk_packed_err_check(struct mmc_card *card,
+struct mmc_async_req *areq)
+{
+   struct mmc_queue_req *mq_mrq = container_of(areq, struct mmc_queue_req,
+   mmc_active);
+   int err, check, status;
+   u8 ext_csd[512];
+
+   check = mmc_blk_err_check(card, areq);
+
+   if (check == MMC_BLK_SUCCESS)
+   return check;
+
+   if (check == MMC_BLK_PARTIAL) {
+   err = get_card_status(card, &status, 0);
+   if (err)
+   return MMC_BLK_ABORT;
+
+   if (status & R1_EXP_EVENT) {
+   err = mmc_send_ext_csd(card, ext_csd);
+   if (err)
+   return MMC_BLK_ABORT;
+
+   if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS + 0] &
+   EXT_CSD_PACKED_FAILURE) &&
+   (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
+EXT_CSD_PACKED_GENERIC_ERROR)) {
+   if (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
+   EXT_CSD_PACKED_INDEXED_ERROR) {
+   /* Make be 0-based */
+   mq_mrq->packed_fail_idx =
+   
ext_csd[EXT_CSD_PACKED_FAILURE_INDEX] - 1;
+   return MMC_BLK_PARTIAL;
+   } else {
+   return MMC_BLK_RETRY;
+   }
+   }
+   } else {
+   return MMC_BLK_RETRY;
+   }
+   }
+
+   if (check != MMC_BLK_ABORT)
+   return MMC_BLK_RETRY;
+   else
+   return MMC_BLK_ABORT;
+}
+
 static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
   struct mmc_card *card,
   int disable_multi,
@@ -1129,6 +1192,211 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
*mqrq,
mmc_queue_bounce_pre(mqrq);
 }

+static u8 mmc_blk_chk_packable(struct mmc_queue *mq, struct request *req)
+{
+   struct request_queue *q = mq->queue;
+   struct mmc_card *card = mq->card;
+   struct request *cur = req, *next = NULL;
+   struct mmc_blk_data *md = mq->data;
+   bool en_rel_wr = card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN;
+   unsigned int req_sectors = 0, phys_segments = 0;
+   unsigned int max_blk_count, max_phys_seg

RE: [PATCH 2/2] mmc: core: Support packed command for eMMC4.5 device

2011-11-02 Thread Seungwon Jeon
S, Venkatraman  wrote:
> On Wed, Nov 2, 2011 at 1:33 PM, Seungwon Jeon  wrote:
> > This patch supports packed command of eMMC4.5 device.
> > Several reads(or writes) can be grouped in packed command
> > and all data of the individual commands can be sent in a
> > single transfer on the bus.
> >
> > Signed-off-by: Seungwon Jeon 
> > ---
> >  drivers/mmc/card/block.c |  355 
> > --
> >  drivers/mmc/card/queue.c |   48 ++-
> >  drivers/mmc/card/queue.h |   12 ++
> >  include/linux/mmc/core.h |    3 +
> >  4 files changed, 404 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> > index a1cb21f..6c49656 100644
> > --- a/drivers/mmc/card/block.c
> > +++ b/drivers/mmc/card/block.c
> > @@ -59,6 +59,13 @@ MODULE_ALIAS("mmc:block");
> >  #define INAND_CMD38_ARG_SECTRIM1 0x81
> >  #define INAND_CMD38_ARG_SECTRIM2 0x88
> >
> > +#define mmc_req_rel_wr(req)    (((req->cmd_flags & REQ_FUA) || \
> > +                       (req->cmd_flags & REQ_META)) && \
> > +                       (rq_data_dir(req) == WRITE))
> > +#define PACKED_CMD_VER         0x01
> > +#define PACKED_CMD_RD          0x01
> > +#define PACKED_CMD_WR          0x02
> > +
> >  static DEFINE_MUTEX(block_mutex);
> >
> >  /*
> > @@ -943,7 +950,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
> >         * kind.  If it was a write, we may have transitioned to
> >         * program mode, which we have to wait for it to complete.
> >         */
> > -       if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
> > +       if ((!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) ||
> > +                       (mq_mrq->packed_cmd == MMC_PACKED_WR_HDR)) {
> >                u32 status;
> >                do {
> >                        int err = get_card_status(card, &status, 5);
> > @@ -980,12 +988,67 @@ static int mmc_blk_err_check(struct mmc_card *card,
> >        if (!brq->data.bytes_xfered)
> >                return MMC_BLK_RETRY;
> >
> > +       if (mq_mrq->packed_cmd != MMC_PACKED_NONE) {
> > +               if (unlikely(brq->data.blocks << 9 != 
> > brq->data.bytes_xfered))
> > +                       return MMC_BLK_PARTIAL;
> > +               else
> > +                       return MMC_BLK_SUCCESS;
> > +       }
> > +
> >        if (blk_rq_bytes(req) != brq->data.bytes_xfered)
> >                return MMC_BLK_PARTIAL;
> >
> >        return MMC_BLK_SUCCESS;
> >  }
> >
> > +static int mmc_blk_packed_err_check(struct mmc_card *card,
> > +                            struct mmc_async_req *areq)
> > +{
> > +       struct mmc_queue_req *mq_mrq = container_of(areq, struct 
> > mmc_queue_req,
> > +                                                   mmc_active);
> > +       int err, check, status;
> > +       u8 ext_csd[512];
> > +
> > +       check = mmc_blk_err_check(card, areq);
> > +
> > +       if (check == MMC_BLK_SUCCESS)
> > +               return check;
> > +
> > +       if (check == MMC_BLK_PARTIAL) {
> > +               err = get_card_status(card, &status, 0);
> > +               if (err)
> > +                       return MMC_BLK_ABORT;
> > +
> > +               if (status & R1_EXP_EVENT) {
> > +                       err = mmc_send_ext_csd(card, ext_csd);
> > +                       if (err)
> > +                               return MMC_BLK_ABORT;
> > +
> > +                       if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS + 0] &
> > +                                               EXT_CSD_PACKED_FAILURE) &&
> > +                                       (ext_csd[EXT_CSD_PACKED_CMD_STATUS] 
> > &
> > +                                        EXT_CSD_PACKED_GENERIC_ERROR)) {
> > +                               if (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
> > +                                               
> > EXT_CSD_PACKED_INDEXED_ERROR) {
> > +                                       /* Make be 0-based */
> > +                                       mq_mrq->packed_fail_idx =
> > +                                               
> > ext_csd[EXT_CSD_PACKED_FAILURE_INDEX] - 1;
> > +                                       return MMC_BLK_PARTIAL;
> > +                               } else {
> > +                                       return MMC_BL

RE: [PATCH 2/2] mmc: core: Support packed command for eMMC4.5 device

2011-11-06 Thread Seungwon Jeon
S, Venkatraman  wrote: 
> On Thu, Nov 3, 2011 at 7:23 AM, Seungwon Jeon  wrote:
> > S, Venkatraman  wrote:
> >> On Wed, Nov 2, 2011 at 1:33 PM, Seungwon Jeon  wrote:
> >> > This patch supports packed command of eMMC4.5 device.
> >> > Several reads(or writes) can be grouped in packed command
> >> > and all data of the individual commands can be sent in a
> >> > single transfer on the bus.
> >> >
> >> > Signed-off-by: Seungwon Jeon 
> >> > ---
> >> >  drivers/mmc/card/block.c |  355 
> >> > --
> >> >  drivers/mmc/card/queue.c |   48 ++-
> >> >  drivers/mmc/card/queue.h |   12 ++
> >> >  include/linux/mmc/core.h |    3 +
> >> >  4 files changed, 404 insertions(+), 14 deletions(-)
> >> >
> >> > diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> >> > index a1cb21f..6c49656 100644
> >> > --- a/drivers/mmc/card/block.c
> >> > +++ b/drivers/mmc/card/block.c
> >> > @@ -59,6 +59,13 @@ MODULE_ALIAS("mmc:block");
> >> >  #define INAND_CMD38_ARG_SECTRIM1 0x81
> >> >  #define INAND_CMD38_ARG_SECTRIM2 0x88
> >> >
> >> > +#define mmc_req_rel_wr(req)    (((req->cmd_flags & REQ_FUA) || \
> >> > +                       (req->cmd_flags & REQ_META)) && \
> >> > +                       (rq_data_dir(req) == WRITE))
> >> > +#define PACKED_CMD_VER         0x01
> >> > +#define PACKED_CMD_RD          0x01
> >> > +#define PACKED_CMD_WR          0x02
> >> > +
> >> >  static DEFINE_MUTEX(block_mutex);
> >> >
> >> >  /*
> >> > @@ -943,7 +950,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
> >> >         * kind.  If it was a write, we may have transitioned to
> >> >         * program mode, which we have to wait for it to complete.
> >> >         */
> >> > -       if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
> >> > +       if ((!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) ||
> >> > +                       (mq_mrq->packed_cmd == MMC_PACKED_WR_HDR)) {
> >> >                u32 status;
> >> >                do {
> >> >                        int err = get_card_status(card, &status, 5);
> >> > @@ -980,12 +988,67 @@ static int mmc_blk_err_check(struct mmc_card *card,
> >> >        if (!brq->data.bytes_xfered)
> >> >                return MMC_BLK_RETRY;
> >> >
> >> > +       if (mq_mrq->packed_cmd != MMC_PACKED_NONE) {
> >> > +               if (unlikely(brq->data.blocks << 9 != 
> >> > brq->data.bytes_xfered))
> >> > +                       return MMC_BLK_PARTIAL;
> >> > +               else
> >> > +                       return MMC_BLK_SUCCESS;
> >> > +       }
> >> > +
> >> >        if (blk_rq_bytes(req) != brq->data.bytes_xfered)
> >> >                return MMC_BLK_PARTIAL;
> >> >
> >> >        return MMC_BLK_SUCCESS;
> >> >  }
> >> >
> >> > +static int mmc_blk_packed_err_check(struct mmc_card *card,
> >> > +                            struct mmc_async_req *areq)
> >> > +{
> >> > +       struct mmc_queue_req *mq_mrq = container_of(areq, struct 
> >> > mmc_queue_req,
> >> > +                                                   mmc_active);
> >> > +       int err, check, status;
> >> > +       u8 ext_csd[512];
> >> > +
> >> > +       check = mmc_blk_err_check(card, areq);
> >> > +
> >> > +       if (check == MMC_BLK_SUCCESS)
> >> > +               return check;
> >> > +
> >> > +       if (check == MMC_BLK_PARTIAL) {
> >> > +               err = get_card_status(card, &status, 0);
> >> > +               if (err)
> >> > +                       return MMC_BLK_ABORT;
> >> > +
> >> > +               if (status & R1_EXP_EVENT) {
> >> > +                       err = mmc_send_ext_csd(card, ext_csd);
> >> > +                       if (err)
> >> > +                               return MMC_BLK_ABORT;
> >> > +
> >> > +                       if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS + 0] &
> >> > +                   

RE: [PATCH 2/2] mmc: core: Support packed command for eMMC4.5 device

2011-11-10 Thread Seungwon Jeon
Maya Erez wrote:
> On Thu, Nov 10, 2011 Maya Erez wrote:
> > S, Venkatraman  wrote:
> >> On Thu, Nov 3, 2011 at 7:23 AM, Seungwon Jeon 
> wrote:
> >> >> > +static u8 mmc_blk_chk_packable(struct mmc_queue *mq, struct
> >> request *req)
> 
> The function prepares the checkable list and not only checks if packing is
> possible, therefore I think its name should change to reflect its real
> action
I labored at naming. Isn't it proper? :)
Do you have any recommendation?
group_pack_req?

> 
> >> >> > +       if (!(md->flags & MMC_BLK_CMD23) &&
> >> >> > +                       !card->ext_csd.packed_event_en)
> >> >> > +               goto no_packed;
> 
> Having the condition with a && can lead to cases where CMD23 is not
> supported and we send packed commands. Therfore the condition should be
> changed to || or be splitted to 2 separate checks.
> Also, according to the standard the generic error flag in
> PACKED_COMMAND_STATUS is set in case of any error and having
> PACKED_EVENT_EN is only optional. Therefore, I don't think that setting
> the packed_event_en should be a mandatory condition for using packed
> coammnds.
... cases where CMD23 is not supported and we send packed commands?
Packed command must not be allowed in such a case.
It works only with predefined mode which is essential fator.
And spec doesn't mentioned PACKED_EVENT_EN must be set.
So Packed command can be sent regardless PACKED_EVENT_EN,
but it's not complete without reporting of error.
Then host driver may suffer error recovery.
Why packed command is used without error reporting?

> 
> >> >> > +       if (mmc_req_rel_wr(cur) &&
> >> >> > +                       (md->flags & MMC_BLK_REL_WR) &&
> >> >> > +                       !en_rel_wr) {
> >> >> > +               goto no_packed;
> >> >> > +       }
> 
> Can you please explain this condition and its purpose?
> 
In the case where reliable write is request but enhanced reliable write
is not supported, write access must be partial according to
reliable write sector count. Because even a single request can be split,
packed command is not allowed in this case.

> >> >> > +               phys_segments +=  next->nr_phys_segments;
> >> >> > +               if (phys_segments > max_phys_segs) {
> >> >> > +                       blk_requeue_request(q, next);
> >> >> > +                       break;
> >> >> > +               }
> >> >> I mentioned this before - if the next request is not packable and
> >> requeued,
> >> >> blk_fetch_request will retrieve it again and this while loop will
> never terminate.
> >> >>
> >> > If next request is not packable, it is requeued and 'break'
> terminates
> >> this loop.
> >> > So it not infinite.
> >> Right !! But that doesn't help finding the commands that are packable.
> Ideally, you'd need to pack all neighbouring requests into one packed
> command.
> >> The way CFQ works, it is not necessary that the fetch would return all
> outstanding
> >> requests that are packable (unless you invoke a forced dispatch) It
> would be good to see some numbers on the number of pack hits /
> misses
> >> that
> >> you would encounter with this logic, on a typical usecase.
> > Is it considered only for CFQ scheduler? How about other I/O scheduler?
> If all requests are drained from scheduler queue forcedly,
> > the number of candidate to be packed can be increased.
> > However we may lose the unique CFQ's strength and MMC D/D may take the
> CFQ's duty.
> > Basically, this patch accommodates the origin order requests from I/O
> scheduler.
> >
> 
> In order to better utilize the packed commands feature and achieve the
> best performance improvements I think that the command packing should be
> done in the block layer, according to the scheduler policy.
> That is, the scheduler should be aware of the capability of the device to
> receive a request list and its constrains (such as maximum number of
> requests, max number of sectors etc) and use this information as a  factor
> to its algorithm.
> This way you keep the decision making in the hands of the scheduler while
> the MMC layer will only have to send this list as a packed command.
> 
Yes, it would be another interesting approach.
Command packing you mentioned means gathering request among same 
direction(read/write)?
Currently I/O scheduler may know device constrains which

RE: [PATCH 2/2] mmc: core: Support packed command for eMMC4.5 device

2011-11-14 Thread Seungwon Jeon
S, Venkatraman  wrote:
> On Fri, Nov 11, 2011 at 12:56 PM, Seungwon Jeon  wrote:
> > Maya Erez wrote:
> >> On Thu, Nov 10, 2011 Maya Erez wrote:
> >> > S, Venkatraman  wrote:
> >> >> On Thu, Nov 3, 2011 at 7:23 AM, Seungwon Jeon 
> >> wrote:
> >> >> >> > +static u8 mmc_blk_chk_packable(struct mmc_queue *mq, struct
> >> >> request *req)
> >>
> >> The function prepares the checkable list and not only checks if packing is
> >> possible, therefore I think its name should change to reflect its real
> >> action
> > I labored at naming. Isn't it proper? :)
> > Do you have any recommendation?
> > group_pack_req?
> >
> >>
> >> >> >> > +       if (!(md->flags & MMC_BLK_CMD23) &&
> >> >> >> > +                       !card->ext_csd.packed_event_en)
> >> >> >> > +               goto no_packed;
> >>
> >> Having the condition with a && can lead to cases where CMD23 is not
> >> supported and we send packed commands. Therfore the condition should be
> >> changed to || or be splitted to 2 separate checks.
> >> Also, according to the standard the generic error flag in
> >> PACKED_COMMAND_STATUS is set in case of any error and having
> >> PACKED_EVENT_EN is only optional. Therefore, I don't think that setting
> >> the packed_event_en should be a mandatory condition for using packed
> >> coammnds.
> > ... cases where CMD23 is not supported and we send packed commands?
> > Packed command must not be allowed in such a case.
> > It works only with predefined mode which is essential fator.
> > And spec doesn't mentioned PACKED_EVENT_EN must be set.
> > So Packed command can be sent regardless PACKED_EVENT_EN,
> > but it's not complete without reporting of error.
> > Then host driver may suffer error recovery.
> > Why packed command is used without error reporting?
> >
> >>
> >> >> >> > +       if (mmc_req_rel_wr(cur) &&
> >> >> >> > +                       (md->flags & MMC_BLK_REL_WR) &&
> >> >> >> > +                       !en_rel_wr) {
> >> >> >> > +               goto no_packed;
> >> >> >> > +       }
> >>
> >> Can you please explain this condition and its purpose?
> >>
> > In the case where reliable write is request but enhanced reliable write
> > is not supported, write access must be partial according to
> > reliable write sector count. Because even a single request can be split,
> > packed command is not allowed in this case.
> >
> >> >> >> > +               phys_segments +=  next->nr_phys_segments;
> >> >> >> > +               if (phys_segments > max_phys_segs) {
> >> >> >> > +                       blk_requeue_request(q, next);
> >> >> >> > +                       break;
> >> >> >> > +               }
> >> >> >> I mentioned this before - if the next request is not packable and
> >> >> requeued,
> >> >> >> blk_fetch_request will retrieve it again and this while loop will
> >> never terminate.
> >> >> >>
> >> >> > If next request is not packable, it is requeued and 'break'
> >> terminates
> >> >> this loop.
> >> >> > So it not infinite.
> >> >> Right !! But that doesn't help finding the commands that are packable.
> >> Ideally, you'd need to pack all neighbouring requests into one packed
> >> command.
> >> >> The way CFQ works, it is not necessary that the fetch would return all
> >> outstanding
> >> >> requests that are packable (unless you invoke a forced dispatch) It
> >> would be good to see some numbers on the number of pack hits /
> >> misses
> >> >> that
> >> >> you would encounter with this logic, on a typical usecase.
> >> > Is it considered only for CFQ scheduler? How about other I/O scheduler?
> >> If all requests are drained from scheduler queue forcedly,
> >> > the number of candidate to be packed can be increased.
> >> > However we may lose the unique CFQ's strength and MMC D/D may take the
> >> CFQ's duty.
> >> > Basically, this patch accommodates the origin order requests from I/O
> >> scheduler.
> >

RE: [PATCH 2/2] mmc: core: Support packed command for eMMC4.5 device

2011-11-14 Thread Seungwon Jeon
Maya Erez wrote:
> > On Fri, Nov 11, 2011 at 12:56 PM, Seungwon Jeon 
> > wrote:
> >> Maya Erez wrote:
> >>> On Thu, Nov 10, 2011 Maya Erez wrote:
> >>> > S, Venkatraman  wrote:
> >>> >> On Thu, Nov 3, 2011 at 7:23 AM, Seungwon Jeon 
> >>> wrote:
> >>> >> >> > +static u8 mmc_blk_chk_packable(struct mmc_queue *mq, struct
> >>> >> request *req)
> >>>
> >>> The function prepares the checkable list and not only checks if packing
> >>> is
> >>> possible, therefore I think its name should change to reflect its real
> >>> action
> >> I labored at naming. Isn't it proper? :)
> >> Do you have any recommendation?
> >> group_pack_req?
> >>
> >>>
> >>> >> >> > +       if (!(md->flags & MMC_BLK_CMD23) &&
> >>> >> >> > +                       !card->ext_csd.packed_event_en)
> >>> >> >> > +               goto no_packed;
> >>>
> >>> Having the condition with a && can lead to cases where CMD23 is not
> >>> supported and we send packed commands. Therfore the condition should be
> >>> changed to || or be splitted to 2 separate checks.
> >>> Also, according to the standard the generic error flag in
> >>> PACKED_COMMAND_STATUS is set in case of any error and having
> >>> PACKED_EVENT_EN is only optional. Therefore, I don't think that setting
> >>> the packed_event_en should be a mandatory condition for using packed
> >>> coammnds.
> >> ... cases where CMD23 is not supported and we send packed commands?
> >> Packed command must not be allowed in such a case.
> >> It works only with predefined mode which is essential fator.
> >> And spec doesn't mentioned PACKED_EVENT_EN must be set.
> >> So Packed command can be sent regardless PACKED_EVENT_EN,
> >> but it's not complete without reporting of error.
> >> Then host driver may suffer error recovery.
> >> Why packed command is used without error reporting?
> Let me better explain my comment:
> If the first condition (!(md->flags & MMC_BLK_CMD23) is 1 (meaning
> MMC_BLK_CMD23 flag is not set), then in case card->ext_csd.packed_event_en
> is 1 the second condition will be 0 and we won't "goto no_packed;". In
> this case, CMD_23 is not supported but we don't exit the function.
> If you want both conditions to be mandatory you need to use here an ||.
Thank you for clearing comment.
This condition will be fixed.

> >>
> >>>
> >>> >> >> > +       if (mmc_req_rel_wr(cur) &&
> >>> >> >> > +                       (md->flags & MMC_BLK_REL_WR) &&
> >>> >> >> > +                       !en_rel_wr) {
> >>> >> >> > +               goto no_packed;
> >>> >> >> > +       }
> >>>
> >>> Can you please explain this condition and its purpose?
> >>>
> >> In the case where reliable write is request but enhanced reliable write
> >> is not supported, write access must be partial according to
> >> reliable write sector count. Because even a single request can be split,
> >> packed command is not allowed in this case.
> >>
> >>> >> >> > +               phys_segments +=  next->nr_phys_segments;
> >>> >> >> > +               if (phys_segments > max_phys_segs) {
> >>> >> >> > +                       blk_requeue_request(q, next);
> >>> >> >> > +                       break;
> >>> >> >> > +               }
> >>> >> >> I mentioned this before - if the next request is not packable and
> >>> >> requeued,
> >>> >> >> blk_fetch_request will retrieve it again and this while loop will
> >>> never terminate.
> >>> >> >>
> >>> >> > If next request is not packable, it is requeued and 'break'
> >>> terminates
> >>> >> this loop.
> >>> >> > So it not infinite.
> >>> >> Right !! But that doesn't help finding the commands that are
> >>> packable.
> >>> Ideally, you'd need to pack all neighbouring requests into one packed
> >>> command.
> >>> >> The way CFQ works, it is not necessary that the fetc

RE: [PATCH 2/2] mmc: core: Support packed command for eMMC4.5 device

2011-11-16 Thread Seungwon Jeon
Maya Erez wrote:
> >> >>> >> >> > +       if (rqc)
> >> >>> >> >> > +               reqs = mmc_blk_chk_packable(mq, rqc);
> >> >>>
> >> >>> It would be best to keep all the calls to blk_fetch_request in the
> >> same
> >> >>> location. Therefore, I suggest to move the call to
> >> mmc_blk_chk_packable
> >> >>> to
> >> >>> mmc/card/queue.c after the first request is fetched.
> >> >>
> >> >> At the first time, I considered that way.
> >> >> I'll do more, if possible.
> > I considered more.
> > I think that mmc_blk_chk_packable would rather be called only for r/w type
> > than all request type(e.g. discard, flush).
> >
> mmc_blk_chk_packable can check the cmd_flags of the request to verify it's
> not a flush/disacrad etc. In such cases will not pack.
Yes. It must be checked, but omitted.
I already have added this check. It will be applied next.

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

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


RE: [PATCH 2/2] mmc: core: Support packed command for eMMC4.5 device

2011-11-16 Thread Seungwon Jeon
Maya Erez wrote:
> >> >> >> >> > +               phys_segments +=  next->nr_phys_segments;
> >> >> >> >> > +               if (phys_segments > max_phys_segs) {
> >> >> >> >> > +                       blk_requeue_request(q, next);
> >> >> >> >> > +                       break;
> >> >> >> >> > +               }
> >> >> >> >> I mentioned this before - if the next request is not packable
> >> and
> >> >> >> requeued,
> >> >> >> >> blk_fetch_request will retrieve it again and this while loop
> >> will
> >> >> never terminate.
> >> >> >> >>
> >> >> >> > If next request is not packable, it is requeued and 'break'
> >> >> terminates
> >> >> >> this loop.
> >> >> >> > So it not infinite.
> >> >> >> Right !! But that doesn't help finding the commands that are
> >> packable.
> >> >> Ideally, you'd need to pack all neighbouring requests into one packed
> >> >> command.
> >> >> >> The way CFQ works, it is not necessary that the fetch would return
> >> all
> >> >> outstanding
> >> >> >> requests that are packable (unless you invoke a forced dispatch)
> >> It
> >> >> would be good to see some numbers on the number of pack hits /
> >> >> misses
> >> >> >> that
> >> >> >> you would encounter with this logic, on a typical usecase.
> >> >> > Is it considered only for CFQ scheduler? How about other I/O
> >> scheduler?
> >> >> If all requests are drained from scheduler queue forcedly,
> >> >> > the number of candidate to be packed can be increased.
> >> >> > However we may lose the unique CFQ's strength and MMC D/D may take
> >> the
> >> >> CFQ's duty.
> >> >> > Basically, this patch accommodates the origin order requests from
> >> I/O
> >> >> scheduler.
> >> >> >
> >> >>
> >> >> In order to better utilize the packed commands feature and achieve
> >> the
> >> >> best performance improvements I think that the command packing should
> >> be
> >> >> done in the block layer, according to the scheduler policy.
> >> >> That is, the scheduler should be aware of the capability of the
> >> device to
> >> >> receive a request list and its constrains (such as maximum number of
> >> >> requests, max number of sectors etc) and use this information as a
> >>  factor
> >> >> to its algorithm.
> >> >> This way you keep the decision making in the hands of the scheduler
> >> while
> >> >> the MMC layer will only have to send this list as a packed command.
> >> >>
> >> > Yes, it would be another interesting approach.
> >> > Command packing you mentioned means gathering request among same
> >> direction(read/write)?
> >> > Currently I/O scheduler may know device constrains which MMC driver
> >> informs
> >> > with the exception of order information for packed command.
> >> > But I think the dependency of I/O scheduler may be able to come up.
> >> > How can MMC layer treat packed command with I/O scheduler which
> >> doesn't support this?
> >>
> >> The very act of packing presumes some sorting and re-ordering at the
> >> I/O scheduler level.
> >> When no such sorting is done (ex. noop), MMC should resort to
> >> non-packed execution, respecting the system configuration choice.
> >>
> >> Looking deeper into this, I think a better approach would be to set
> >> the prep_rq_fn of the request_queue, with a custom mmc function that
> >> decides if the requests are packable or not, and return a
> >> BLKPREP_DEFER for those that can't be packed.
> >
> > MMC layer anticipates the favorable requests for packing from I/O
> > scheduler.
> > Obviously request order from I/O scheduler might be poor for packing and
> > requests can't be packed.
> > But that doesn't mean mmc layer need to wait a better pack-case.
> > BLKPREP_DEFER may give rise to I/O latency. Top of request will be
> > deferred next time.
> > If request can't be pa

RE: [PATCH] mmc: core: Add packed command for eMMC4.5 device

2011-11-16 Thread Seungwon Jeon
Maya Erez wrote:
> 
> > +   if (reqs >= 2) {
> > +   mmc_blk_packed_hdr_wrq_prep(mq->mqrq_cur, card, 
> > mq, reqs);
> > +   if (rq_data_dir(rqc) == READ) {
> > +   areq = &mq->mqrq_cur->mmc_active;
> > +   mmc_wait_for_req(card->host, areq->mrq);
> Packing read requests requires preparation of two requests. After sending
> the header we wait for its completion before sending the next request
> (mmc_wait_for_req is used). Therefore, if we try to pack 2 read requests
> we might end up with worse performance in comparison to sending each
> request by itself (which allows the preparation of one request while the
> other is sent).
> I suggest to check the size of the packed commands list and in case it is
> less than 3 send the requests one by one. If you move mmc_blk_chk_packable
> to queue.c after the first fetch this change should be very easy and can
> be done by removing the requests from the packed_list and calling issue_fn
> for each one of them.

Sending header for packed read which doesn't require nand program
unlike normal data, so it may not spend long time.
Which point you think is the overhead of packed two-requests
in comparison to individual request?
> 
> Thanks,
> Maya Erez
> Consultant for Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
> 
> 
> 
> 
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


RE: [PATCH] mmc: core: Add packed command for eMMC4.5 device

2011-11-17 Thread Seungwon Jeon
Sahitya Tummala wrote:
> Hi,
> 
> On 10/27/2011 4:24 PM, Seungwon Jeon wrote:
> >
> > +static int mmc_blk_packed_err_check(struct mmc_card *card,
> > +struct mmc_async_req *areq)
> > +{
> > +   struct mmc_queue_req *mq_mrq = container_of(areq, struct mmc_queue_req,
> > +   mmc_active);
> > +   int err, check, status;
> > +   u8 ext_csd[512];
> > +
> > +   check = mmc_blk_err_check(card, areq);
> > +
> > +   if (check == MMC_BLK_SUCCESS)
> > +   return check;
> > +
> > +   if (check == MMC_BLK_PARTIAL) {
> > +   err = get_card_status(card,&status, 0);
> > +   if (err)
> > +   return MMC_BLK_ABORT;
> > +
> > +   if (status&  R1_EXP_EVENT) {
> > +   err = mmc_send_ext_csd(card, ext_csd);
> > +   if (err)
> > +   return MMC_BLK_ABORT;
> > +
> > +   if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS + 0]&
> > +   EXT_CSD_PACKED_FAILURE)&&
> > +   (ext_csd[EXT_CSD_PACKED_CMD_STATUS]&
> > +EXT_CSD_PACKED_GENERIC_ERROR)) {
> > +   if (ext_csd[EXT_CSD_PACKED_CMD_STATUS]&
> > +   EXT_CSD_PACKED_INDEXED_ERROR) {
> > +   /* Make be 0-based */
> > +   mq_mrq->packed_fail_idx =
> > +   
> > ext_csd[EXT_CSD_PACKED_FAILURE_INDEX] - 1;
> > +   return MMC_BLK_PARTIAL;
> > +   } else {
> > +   return MMC_BLK_RETRY;
> > +   }
> > +   }
> > +   } else {
> > +   return MMC_BLK_RETRY;
> > +   }
> > +   }
> > +
> > +   if (check != MMC_BLK_ABORT)
> > +   return MMC_BLK_RETRY;
> > +   else
> > +   return MMC_BLK_ABORT;
> 
> The current code does not return other errors (MMC_BLK_CMD_ERR,
> MMC_BLK_ECC_ERR and MMC_BLK_DATA_ERR) returned by mmc_blk_err_check().
> Why not return check here?
Currently retry is taken in case of other errors.
But some case needs to be split.
> 
> > +}
> > +
> >   static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
> >struct mmc_card *card,
> >int disable_multi,
> > @@ -1126,6 +1187,207 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
> > *mqrq,
> > mmc_queue_bounce_pre(mqrq);
> >   }
> >
> > +static u8 mmc_blk_chk_packable(struct mmc_queue *mq, struct request *req)
> > +{
> > +   struct request_queue *q = mq->queue;
> > +   struct mmc_card *card = mq->card;
> > +   struct request *cur = req, *next = NULL;
> > +   struct mmc_blk_data *md = mq->data;
> > +   bool en_rel_wr = card->ext_csd.rel_param&  EXT_CSD_WR_REL_PARAM_EN;
> > +   unsigned int req_sectors = 0, phys_segments = 0;
> > +   unsigned int max_blk_count, max_phys_segs;
> > +   u8 max_packed_rw = 0;
> > +   u8 reqs = 0;
> > +
> > +   if (!(md->flags&  MMC_BLK_CMD23)&&
> > +   !card->ext_csd.packed_event_en)
> > +   goto no_packed;
> > +
> > +   if (rq_data_dir(cur) == READ)
> > +   max_packed_rw = card->ext_csd.max_packed_reads;
> > +   else
> > +   max_packed_rw = card->ext_csd.max_packed_writes;
> > +
> > +   if (max_packed_rw == 0)
> > +   goto no_packed;
> > +
> > +   if (mmc_req_rel_wr(cur)&&
> > +   (md->flags&  MMC_BLK_REL_WR)&&
> > +   !en_rel_wr) {
> > +   goto no_packed;
> > +   }
> > +
> > +   max_blk_count = min(card->host->max_blk_count,
> > +   card->host->max_req_size>>  9);
> > +   max_phys_segs = queue_max_segments(q);
> > +   req_sectors += blk_rq_sectors(cur);
> > +   phys_segments += req->nr_phys_segments;
> > +
> > +   if (rq_data_dir(cur) == WRITE) {
> > +   req_sectors++;
> > +   phys_segments++;
> > +   }
> > +
> > +   while (reqs<  max_packed_rw - 1) {
> 
> What if the number of requests exceeds the packed header size defined?
Currently not considered.
That case is 

[PATCH 1/2] mmc: core: Separate the timeout value for cache-ctrl

2011-11-24 Thread Seungwon Jeon
Turning the cache off implies flushing cache which doesn't define
maximum timeout unlike cache-on. This patch will apply the generic
CMD6 timeout only for cache-on. Additionally the kernel message is
added for checking failure case of cache-on.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/core.c |   22 +-
 drivers/mmc/core/mmc.c  |   12 ++--
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 271efea..481b090 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2270,6 +2270,7 @@ EXPORT_SYMBOL(mmc_flush_cache);
 int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
 {
struct mmc_card *card = host->card;
+   unsigned int timeout;
int err = 0;
 
if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) ||
@@ -2280,16 +2281,19 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
(card->ext_csd.cache_size > 0)) {
enable = !!enable;
 
-   if (card->ext_csd.cache_ctrl ^ enable)
+   if (card->ext_csd.cache_ctrl ^ enable) {
+   timeout = enable ? card->ext_csd.generic_cmd6_time : 0;
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-   EXT_CSD_CACHE_CTRL, enable, 0);
-   if (err)
-   pr_err("%s: cache %s error %d\n",
-   mmc_hostname(card->host),
-   enable ? "on" : "off",
-   err);
-   else
-   card->ext_csd.cache_ctrl = enable;
+   EXT_CSD_CACHE_CTRL, enable, timeout);
+
+   if (err)
+   pr_err("%s: cache %s error %d\n",
+   mmc_hostname(card->host),
+   enable ? "on" : "off",
+   err);
+   else
+   card->ext_csd.cache_ctrl = enable;
+   }
}
 
return err;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index a1223bd..1e1dda9 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1066,14 +1066,22 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if ((host->caps2 & MMC_CAP2_CACHE_CTRL) &&
card->ext_csd.cache_size > 0) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-   EXT_CSD_CACHE_CTRL, 1, 0);
+   EXT_CSD_CACHE_CTRL, 1,
+   card->ext_csd.generic_cmd6_time);
if (err && err != -EBADMSG)
goto free_card;
 
/*
 * Only if no error, cache is turned on successfully.
 */
-   card->ext_csd.cache_ctrl = err ? 0 : 1;
+   if (err) {
+   pr_warning("%s: Cache is supported, "
+   "but failed to turn on (%d)\n",
+   mmc_hostname(card->host), err);
+   err = 0;
+   } else {
+   card->ext_csd.cache_ctrl = 1;
+   }
}
 
if (!oldcard)
-- 
1.7.0.4

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


[PATCH 2/2] mmc: core: Add claiming a host during mmc_cache_ctrl

2011-11-24 Thread Seungwon Jeon
While calling mmc_cache_ctrl() a host is not claimed. This patch
adds the mmc_try_claim_host() for quick response in suspend.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/core.c |8 +++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 481b090..703ff11 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2314,7 +2314,13 @@ int mmc_suspend_host(struct mmc_host *host)
cancel_delayed_work(&host->disable);
cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
-   err = mmc_cache_ctrl(host, 0);
+   if (mmc_try_claim_host(host)) {
+   err = mmc_cache_ctrl(host, 0);
+   mmc_do_release_host(host);
+   } else {
+   err = -EBUSY;
+   }
+
if (err)
goto out;
 
-- 
1.7.0.4

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


RE: [PATCH 2/2] mmc: core: Support packed command for eMMC4.5 device

2011-11-28 Thread Seungwon Jeon
Maya Erez wrote:
> >> >> On Wed, Nov 2, 2011 at 1:33 PM, Seungwon Jeon 
> >> wrote:
> >> >> > @@ -943,7 +950,8 @@ static int mmc_blk_err_check(struct mmc_card
> >> *card,
> >> >> >         * kind.  If it was a write, we may have transitioned to
>       * program mode, which we have to wait for it to complete.
>       */
> >> >> > -       if (!mmc_host_is_spi(card->host) && rq_data_dir(req) !=
> >> READ) {
> >> >> > +       if ((!mmc_host_is_spi(card->host) && rq_data_dir(req) !=
> >> READ) ||
> >> >> > +                       (mq_mrq->packed_cmd == MMC_PACKED_WR_HDR))
> Since the header's direction is WRITE I don't think we also need to check
> if mq_mrq->packed_cmd == MMC_PACKED_WR_HDR since it will be covered by the
> original condition.
The header is written. But origin request is about read.
That means rq_data_dir(req) is READ. So new condition is needed.
> >> {
> >> >> >                u32 status;
> >> >> >                do {
> >> >> >                        int err = get_card_status(card, &status,
> 5);
> A general question, not related specifically to packed commands - Do you
> know why the status is not checked to see which error we got?
This status is for checking whether the card is ready for new data.
> >> >> > @@ -980,12 +988,67 @@ static int mmc_blk_err_check(struct mmc_card
> >> *card,
> >> >> >        if (!brq->data.bytes_xfered)
> >> >> >                return MMC_BLK_RETRY;
> >> >> >
> >> >> > +       if (mq_mrq->packed_cmd != MMC_PACKED_NONE) {
> >> >> > +               if (unlikely(brq->data.blocks << 9 !=
> >> brq->data.bytes_xfered))
> >> >> > +                       return MMC_BLK_PARTIAL;
> >> >> > +               else
> >> >> > +                       return MMC_BLK_SUCCESS;
> >> >> > +       }
> >> >> > +
> >> >> >        if (blk_rq_bytes(req) != brq->data.bytes_xfered)
> >> >> >                return MMC_BLK_PARTIAL;
> >> >> >
> >> >> >        return MMC_BLK_SUCCESS;
> >> >> >  }
> >> >> >
> >> >> > +static int mmc_blk_packed_err_check(struct mmc_card *card, +
>                        struct mmc_async_req *areq)
> >> >> > +{
> >> >> > +       struct mmc_queue_req *mq_mrq = container_of(areq, struct
> >> mmc_queue_req,
> >> >> > +                                                   mmc_active); +
>       int err, check, status;
> >> >> > +       u8 ext_csd[512];
> >> >> > +
> >> >> > +       check = mmc_blk_err_check(card, areq);
> >> >> > +
> >> >> > +       if (check == MMC_BLK_SUCCESS)
> >> >> > +               return check;
> I think we need to check the status for all cases and not only in case of
> MMC_BLK_PARTIAL. For example, in cases where the header was traferred
> successfully but had logic errors (wrong number of sectors etc.)
> mmc_blk_err_check will return MMC_BLK_SUCCESS although the packed commands
> failed.
Similarly, Sahitya Tummala is already mentioned this.
Other error case will be checked in next version.
The case you suggested is about read or write?
Device may detect error and stop transferring the data.
> >> >> > +
> >> >> > +       if (check == MMC_BLK_PARTIAL) {
> >> >> > +               err = get_card_status(card, &status, 0);
> >> >> > +               if (err)
> >> >> > +                       return MMC_BLK_ABORT;
> >> >> > +
> >> >> > +               if (status & R1_EXP_EVENT) {
> >> >> > +                       err = mmc_send_ext_csd(card, ext_csd); +
>                     if (err)
> >> >> > +                               return MMC_BLK_ABORT;
> >> >> > +
> >> >> > +                       if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS +
> 0]
> why do we need the + 0?
It is explicit expression, no more, no less.
Actually, there is no need.
> >> &
> >> >> > +
> >> EXT_CSD_PACKED_INDEXED_ERROR) {
> >> >> > +                                       /* Make be 0-based */
> The comment is not understood
PACKED_FAILURE_INDEX starts from '1'
It is converted to 0-base for use.
> >> >> > +                                       mq_mrq->packed_fail_idx =
> +
> Thanks,
> Maya Erez
> --
> Seny by a Consultant for Qualcomm innovation center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


RE: [PATCH 2/2] mmc: core: Support packed command for eMMC4.5 device

2011-12-02 Thread Seungwon Jeon
Maya Erez wrote:
> > Maya Erez wrote:
> >> >> >> On Wed, Nov 2, 2011 at 1:33 PM, Seungwon Jeon
> >> 
> >> >> wrote:
> >> >> >> > @@ -980,12 +988,67 @@ static int mmc_blk_err_check(struct
> >> mmc_card
> >> >> *card,
> >> >> >> >        if (!brq->data.bytes_xfered)
> >> >> >> >                return MMC_BLK_RETRY;
> >> >> >> >
> >> >> >> > +       if (mq_mrq->packed_cmd != MMC_PACKED_NONE) {
> >> >> >> > +               if (unlikely(brq->data.blocks << 9 !=
> >> >> brq->data.bytes_xfered))
> >> >> >> > +                       return MMC_BLK_PARTIAL;
> >> >> >> > +               else
> >> >> >> > +                       return MMC_BLK_SUCCESS;
> >> >> >> > +       }
> >> >> >> > +
> >> >> >> >        if (blk_rq_bytes(req) != brq->data.bytes_xfered)
> >> >> >> >                return MMC_BLK_PARTIAL;
> >> >> >> >
> >> >> >> >        return MMC_BLK_SUCCESS;
> >> >> >> >  }
> >> >> >> >
> >> >> >> > +static int mmc_blk_packed_err_check(struct mmc_card *card, +
> >>                        struct mmc_async_req *areq)
> >> >> >> > +{
> >> >> >> > +       struct mmc_queue_req *mq_mrq = container_of(areq, struct
> >> >> mmc_queue_req,
> >> >> >> > +                                                   mmc_active);
> >> +
> >>       int err, check, status;
> >> >> >> > +       u8 ext_csd[512];
> >> >> >> > +
> >> >> >> > +       check = mmc_blk_err_check(card, areq);
> >> >> >> > +
> >> >> >> > +       if (check == MMC_BLK_SUCCESS)
> >> >> >> > +               return check;
> >> I think we need to check the status for all cases and not only in case
> >> of
> >> MMC_BLK_PARTIAL. For example, in cases where the header was traferred
> >> successfully but had logic errors (wrong number of sectors etc.)
> >> mmc_blk_err_check will return MMC_BLK_SUCCESS although the packed
> >> commands
> >> failed.
> > Similarly, Sahitya Tummala is already mentioned this.
> > Other error case will be checked in next version.
> > The case you suggested is about read or write?
> > Device may detect error and stop transferring the data.
> Sahitya suggested to also check other error cases that mmc_blk_err_check
> returns (such as MMC_BLK_CMD_ERR, MMC_BLK_ECC_ERR and MMC_BLK_DATA_ERR).
> I suggest to also check the exception bit in the status even if
> mmc_blk_err_check returned success, since mmc_blk_err_check might not
> catch all the packed commands failures. One example for such a failure is
> when the header of read packed commands will have logical error.
This part is modified in next version.

Thanks,
Seungwon Jeon.

> Thanks,
> Maya
> --
> Seny by a Consultant for Qualcomm innovation center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
> 
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


[PATCH v2 0/2] mmc: core: Support packed command feature of eMMC4.5

2011-12-02 Thread Seungwon Jeon
This patch-set adds support of packed command feature
for eMMC4.5 devices.

Changes in v2:
- Fixed the packed read sequence and error handling.
- Applied checking the exception status for all cases with
   the comments from Maya Erez and Sahitya Tummala.
- Fixed preparing the packed list with the comment from Maya Erez and 
Venkatraman.

Seungwon Jeon (2):
  mmc: core: Add packed command feature of eMMC4.5
  mmc: core: Support packed command for eMMC4.5 device

 drivers/mmc/card/block.c   |  454 ++--
 drivers/mmc/card/queue.c   |   48 +-
 drivers/mmc/card/queue.h   |   13 ++
 drivers/mmc/core/mmc.c |   24 +++
 drivers/mmc/core/mmc_ops.c |1 +
 include/linux/mmc/card.h   |3 +
 include/linux/mmc/core.h   |3 +
 include/linux/mmc/host.h   |1 +
 include/linux/mmc/mmc.h|   15 ++
 9 files changed, 538 insertions(+), 24 deletions(-)

Best regards,
Seungwon Jeon.
--
1.7.2.3


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


[PATCH v2 2/2] mmc: core: Support packed command for eMMC4.5 device

2011-12-02 Thread Seungwon Jeon
This patch supports packed command of eMMC4.5 device.
Several reads(or writes) can be grouped in packed command
and all data of the individual commands can be sent in a
single transfer on the bus.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/card/block.c   |  454 ++--
 drivers/mmc/card/queue.c   |   48 +-
 drivers/mmc/card/queue.h   |   13 ++
 drivers/mmc/core/mmc_ops.c |1 +
 include/linux/mmc/core.h   |3 +
 5 files changed, 495 insertions(+), 24 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index ad0fb8d..f128df3 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -59,6 +59,13 @@ MODULE_ALIAS("mmc:block");
 #define INAND_CMD38_ARG_SECTRIM1 0x81
 #define INAND_CMD38_ARG_SECTRIM2 0x88
 
+#define mmc_req_rel_wr(req)(((req->cmd_flags & REQ_FUA) || \
+   (req->cmd_flags & REQ_META)) && \
+   (rq_data_dir(req) == WRITE))
+#define PACKED_CMD_VER 0x01
+#define PACKED_CMD_RD  0x01
+#define PACKED_CMD_WR  0x02
+
 static DEFINE_MUTEX(block_mutex);
 
 /*
@@ -99,6 +106,7 @@ struct mmc_blk_data {
 #define MMC_BLK_WRITE  BIT(1)
 #define MMC_BLK_DISCARDBIT(2)
 #define MMC_BLK_SECDISCARD BIT(3)
+#define MMC_BLK_WR_HDR BIT(4)
 
/*
 * Only set in main mmc_blk_data associated
@@ -951,7 +959,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
 * kind.  If it was a write, we may have transitioned to
 * program mode, which we have to wait for it to complete.
 */
-   if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
+   if ((!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) ||
+   (mq_mrq->packed_cmd == MMC_PACKED_WR_HDR)) {
u32 status;
do {
int err = get_card_status(card, &status, 5);
@@ -988,12 +997,60 @@ static int mmc_blk_err_check(struct mmc_card *card,
if (!brq->data.bytes_xfered)
return MMC_BLK_RETRY;
 
+   if (mq_mrq->packed_cmd != MMC_PACKED_NONE) {
+   if (unlikely(brq->data.blocks << 9 != brq->data.bytes_xfered))
+   return MMC_BLK_PARTIAL;
+   else
+   return MMC_BLK_SUCCESS;
+   }
+
if (blk_rq_bytes(req) != brq->data.bytes_xfered)
return MMC_BLK_PARTIAL;
 
return MMC_BLK_SUCCESS;
 }
 
+static int mmc_blk_packed_err_check(struct mmc_card *card,
+struct mmc_async_req *areq)
+{
+   struct mmc_queue_req *mq_rq = container_of(areq, struct mmc_queue_req,
+   mmc_active);
+   struct request *req = mq_rq->req;
+   int err, check, status;
+   u8 ext_csd[512];
+
+   check = mmc_blk_err_check(card, areq);
+   err = get_card_status(card, &status, 0);
+   if (err) {
+   pr_err("%s: error %d sending status command\n",
+   req->rq_disk->disk_name, err);
+   return MMC_BLK_ABORT;
+   }
+
+   if (status & R1_EXP_EVENT) {
+   err = mmc_send_ext_csd(card, ext_csd);
+   if (err) {
+   pr_err("%s: error %d sending ext_csd\n",
+   req->rq_disk->disk_name, err);
+   return MMC_BLK_ABORT;
+   }
+
+   if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS] &
+   EXT_CSD_PACKED_FAILURE) &&
+   (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
+EXT_CSD_PACKED_GENERIC_ERROR)) {
+   if (ext_csd[EXT_CSD_PACKED_CMD_STATUS] &
+   EXT_CSD_PACKED_INDEXED_ERROR) {
+   mq_rq->packed_fail_idx =
+   ext_csd[EXT_CSD_PACKED_FAILURE_INDEX] - 
1;
+   return MMC_BLK_PARTIAL;
+   }
+   }
+   }
+
+   return check;
+}
+
 static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
   struct mmc_card *card,
   int disable_multi,
@@ -1137,10 +1194,238 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
*mqrq,
mmc_queue_bounce_pre(mqrq);
 }
 
+static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req)
+{
+   struct request_queue *q = mq->queue;
+   struct mmc_card *card = mq->card;
+   struct request *cur = req, *next = NULL;
+   struct mmc_blk_data *md = mq->data;
+   bool en_rel_wr = card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN;
+   unsigned int req_sectors = 0, phys_segments = 0;
+   unsigne

[PATCH v2 1/2] mmc: core: Add packed command feature of eMMC4.5

2011-12-02 Thread Seungwon Jeon
This patch adds packed command feature of eMMC4.5.
The maximum number for packing read(or write) is offered
and exception event relevant to packed command which is
used for error handling is enabled. If host wants to use
this feature, MMC_CAP2_PACKED_CMD should be set.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/mmc.c   |   24 
 include/linux/mmc/card.h |3 +++
 include/linux/mmc/host.h |1 +
 include/linux/mmc/mmc.h  |   15 +++
 4 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index e8b6b5d..fc8a4cf 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -487,6 +487,11 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 
*ext_csd)
ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+
+   card->ext_csd.max_packed_writes =
+   ext_csd[EXT_CSD_MAX_PACKED_WRITES];
+   card->ext_csd.max_packed_reads =
+   ext_csd[EXT_CSD_MAX_PACKED_READS];
}
 
 out:
@@ -1076,6 +1081,25 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
card->ext_csd.cache_ctrl = err ? 0 : 1;
}
 
+   if ((host->caps2 & MMC_CAP2_PACKED_CMD) &&
+   (card->ext_csd.max_packed_writes > 0) &&
+   (card->ext_csd.max_packed_reads > 0)) {
+   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+   EXT_CSD_EXP_EVENTS_CTRL,
+   EXT_CSD_PACKED_EVENT_EN,
+   card->ext_csd.generic_cmd6_time);
+   if (err && err != -EBADMSG)
+   goto free_card;
+   if (err) {
+   pr_warning("%s: Enabling packed event failed\n",
+   mmc_hostname(card->host));
+   card->ext_csd.packed_event_en = 0;
+   err = 0;
+   } else {
+   card->ext_csd.packed_event_en = 1;
+   }
+   }
+
if (!oldcard)
host->card = card;
 
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 6402d92..73e8add 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -52,6 +52,9 @@ struct mmc_ext_csd {
u8  part_config;
u8  cache_ctrl;
u8  rst_n_function;
+   u8  max_packed_writes;
+   u8  max_packed_reads;
+   u8  packed_event_en;
unsigned intpart_time;  /* Units: ms */
unsigned intsa_timeout; /* Units: 100ns */
unsigned intgeneric_cmd6_time;  /* Units: 10ms */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 9a03d03..5667035 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -242,6 +242,7 @@ struct mmc_host {
 #define MMC_CAP2_CACHE_CTRL(1 << 1)/* Allow cache control */
 #define MMC_CAP2_POWEROFF_NOTIFY (1 << 2)  /* Notify poweroff supported */
 #define MMC_CAP2_NO_MULTI_READ (1 << 3)/* Multiblock reads don't work 
*/
+#define MMC_CAP2_PACKED_CMD(1 << 4)/* Allow packed command */
 
mmc_pm_flag_t   pm_caps;/* supported pm features */
unsigned intpower_notify_type;
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 0e71356..1b94c4f 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -138,6 +138,7 @@ static inline bool mmc_op_multi(u32 opcode)
 #define R1_CURRENT_STATE(x)((x & 0x1E00) >> 9) /* sx, b (4 bits) */
 #define R1_READY_FOR_DATA  (1 << 8)/* sx, a */
 #define R1_SWITCH_ERROR(1 << 7)/* sx, c */
+#define R1_EXP_EVENT   (1 << 6)/* sr, a */
 #define R1_APP_CMD (1 << 5)/* sr, c */
 
 #define R1_STATE_IDLE  0
@@ -273,6 +274,10 @@ struct _mmc_csd {
 #define EXT_CSD_FLUSH_CACHE32  /* W */
 #define EXT_CSD_CACHE_CTRL 33  /* R/W */
 #define EXT_CSD_POWER_OFF_NOTIFICATION 34  /* R/W */
+#define EXT_CSD_PACKED_FAILURE_INDEX   35  /* RO */
+#define EXT_CSD_PACKED_CMD_STATUS  36  /* RO */
+#define EXT_CSD_EXP_EVENTS_STATUS  54  /* RO, 2 bytes */
+#define EXT_CSD_EXP_EVENTS_CTRL56  /* R/W, 2 bytes */
 #define EXT_CSD_GP_SIZE_MULT   143 /* R/W */
 #define EXT_CSD_PARTITION_ATTRIBUTE156 /* R/W */
 #define EXT_CSD_PARTITION_SUPPORT  160 /* RO */
@@

mmc: dw_mmc: Add more capabilities field

2011-12-08 Thread Seungwon Jeon
Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/host/dw_mmc.c  |6 ++
 include/linux/mmc/dw_mmc.h |1 +
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 3aaeb08..366df6b 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1681,6 +1681,12 @@ static int __init dw_mci_init_slot(struct dw_mci *host, 
unsigned int id)
else
mmc->caps = 0;
 
+   if (host->pdata->caps2)
+   mmc->caps2 = host->pdata->caps2;
+   else
+   mmc->caps2 = 0;
+
+
if (host->pdata->get_bus_wd)
if (host->pdata->get_bus_wd(slot->id) >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 6dc9b80..e8779c6 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -214,6 +214,7 @@ struct dw_mci_board {
unsigned int bus_hz; /* Bus speed */
 
unsigned int caps;  /* Capabilities */
+   unsigned int caps2; /* More capabilities */
/*
 * Override fifo depth. If 0, autodetect it from the FIFOTH register,
 * but note that this may not be reliable after a bootloader has used
-- 
1.7.0.4


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


[PATCH] mmc: dw_mmc: Add more capabilities field

2011-12-08 Thread Seungwon Jeon
This patch adds another capabilities field for MMC_CAPS2_XXX.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/host/dw_mmc.c  |6 ++
 include/linux/mmc/dw_mmc.h |1 +
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 3aaeb08..366df6b 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1681,6 +1681,12 @@ static int __init dw_mci_init_slot(struct dw_mci *host, 
unsigned int id)
else
mmc->caps = 0;
 
+   if (host->pdata->caps2)
+   mmc->caps2 = host->pdata->caps2;
+   else
+   mmc->caps2 = 0;
+
+
if (host->pdata->get_bus_wd)
if (host->pdata->get_bus_wd(slot->id) >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 6dc9b80..e8779c6 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -214,6 +214,7 @@ struct dw_mci_board {
unsigned int bus_hz; /* Bus speed */
 
unsigned int caps;  /* Capabilities */
+   unsigned int caps2; /* More capabilities */
/*
 * Override fifo depth. If 0, autodetect it from the FIFOTH register,
 * but note that this may not be reliable after a bootloader has used
-- 
1.7.0.4


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


[PATCH RESEND] mmc: dw_mmc: Support predefined mutiple block transfers

2011-12-08 Thread Seungwon Jeon
This patch adds the support for predefined multiple block read/write.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/host/dw_mmc.c |   34 --
 1 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 366df6b..f8301a7 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -588,11 +588,11 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
mci_writel(host, CTYPE, (slot->ctype << slot->id));
 }
 
-static void dw_mci_start_request(struct dw_mci *host,
-struct dw_mci_slot *slot)
+static void __dw_mci_start_request(struct dw_mci *host,
+  struct dw_mci_slot *slot,
+  struct mmc_command *cmd)
 {
struct mmc_request *mrq;
-   struct mmc_command *cmd;
struct mmc_data *data;
u32 cmdflags;
 
@@ -610,14 +610,13 @@ static void dw_mci_start_request(struct dw_mci *host,
host->completed_events = 0;
host->data_status = 0;
 
-   data = mrq->data;
+   data = cmd->data;
if (data) {
dw_mci_set_timeout(host);
mci_writel(host, BYTCNT, data->blksz*data->blocks);
mci_writel(host, BLKSIZ, data->blksz);
}
 
-   cmd = mrq->cmd;
cmdflags = dw_mci_prepare_command(slot->mmc, cmd);
 
/* this is the first command, send the initialization clock */
@@ -635,6 +634,16 @@ static void dw_mci_start_request(struct dw_mci *host,
host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop);
 }
 
+static void dw_mci_start_request(struct dw_mci *host,
+struct dw_mci_slot *slot)
+{
+   struct mmc_request *mrq = slot->mrq;
+   struct mmc_command *cmd;
+
+   cmd = mrq->sbc ? mrq->sbc : mrq->cmd;
+   __dw_mci_start_request(host, slot, cmd);
+}
+
 /* must be called with host->lock held */
 static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
 struct mmc_request *mrq)
@@ -889,7 +898,14 @@ static void dw_mci_tasklet_func(unsigned long priv)
cmd = host->cmd;
host->cmd = NULL;
set_bit(EVENT_CMD_COMPLETE, &host->completed_events);
-   dw_mci_command_complete(host, host->mrq->cmd);
+   dw_mci_command_complete(host, cmd);
+   if ((cmd == host->mrq->sbc) && !cmd->error) {
+   prev_state = state = STATE_SENDING_CMD;
+   __dw_mci_start_request(host, host->cur_slot,
+  host->mrq->cmd);
+   goto unlock;
+   }
+
if (!host->mrq->data || cmd->error) {
dw_mci_request_end(host, host->mrq);
goto unlock;
@@ -967,6 +983,12 @@ static void dw_mci_tasklet_func(unsigned long priv)
goto unlock;
}
 
+   if (host->mrq->sbc && !data->error) {
+   data->stop->error = 0;
+   dw_mci_request_end(host, host->mrq);
+   goto unlock;
+   }
+
prev_state = state = STATE_SENDING_STOP;
if (!data->error)
send_stop_cmd(host, data);
-- 
1.7.0.4


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


[PATCH v2 0/2] mmc: core: Fix cache control for eMMC4.5

2011-12-09 Thread Seungwon Jeon
This patch-set fixed the cache control for eMMC4.5

Changes in v2:
- clear the cache_ctrl flag for a failure(enabling cache)

Seungwon Jeon (2):
  mmc: core: Separate the timeout value for cache-ctrl
  mmc: core: Add claiming a host during mmc_cache_ctrl

 drivers/mmc/core/core.c |   29 +++--
 drivers/mmc/core/mmc.c  |   13 +++--
 2 files changed, 30 insertions(+), 12 deletions(-)

Best regards,
Seungwon Jeon.
--
1.7.2.3


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


[PATCH v2 1/2] mmc: core: Separate the timeout value for cache-ctrl

2011-12-09 Thread Seungwon Jeon
Turning the cache off implies flushing cache which doesn't define
maximum timeout unlike cache-on. This patch will apply the generic
CMD6 timeout only for cache-on. Additionally the kernel message is
added for checking failure case of cache-on.

Signed-off-by: Seungwon Jeon 
---
Changes in v2:
- clear the cache_ctrl flag for a failure(enabling cache)

 drivers/mmc/core/core.c |   21 -
 drivers/mmc/core/mmc.c  |   13 +++--
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index a2aa860..b96b5ae 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2315,6 +2315,7 @@ EXPORT_SYMBOL(mmc_flush_cache);
 int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
 {
struct mmc_card *card = host->card;
+   unsigned int timeout;
int err = 0;
 
if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) ||
@@ -2325,16 +2326,18 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
(card->ext_csd.cache_size > 0)) {
enable = !!enable;
 
-   if (card->ext_csd.cache_ctrl ^ enable)
+   if (card->ext_csd.cache_ctrl ^ enable) {
+   timeout = enable ? card->ext_csd.generic_cmd6_time : 0;
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-   EXT_CSD_CACHE_CTRL, enable, 0);
-   if (err)
-   pr_err("%s: cache %s error %d\n",
-   mmc_hostname(card->host),
-   enable ? "on" : "off",
-   err);
-   else
-   card->ext_csd.cache_ctrl = enable;
+   EXT_CSD_CACHE_CTRL, enable, timeout);
+   if (err)
+   pr_err("%s: cache %s error %d\n",
+   mmc_hostname(card->host),
+   enable ? "on" : "off",
+   err);
+   else
+   card->ext_csd.cache_ctrl = enable;
+   }
}
 
return err;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 006e932..71cb810 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1077,14 +1077,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if ((host->caps2 & MMC_CAP2_CACHE_CTRL) &&
card->ext_csd.cache_size > 0) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-   EXT_CSD_CACHE_CTRL, 1, 0);
+   EXT_CSD_CACHE_CTRL, 1,
+   card->ext_csd.generic_cmd6_time);
if (err && err != -EBADMSG)
goto free_card;
 
/*
 * Only if no error, cache is turned on successfully.
 */
-   card->ext_csd.cache_ctrl = err ? 0 : 1;
+   if (err) {
+   pr_warning("%s: Cache is supported, "
+   "but failed to turn on (%d)\n",
+   mmc_hostname(card->host), err);
+   card->ext_csd.cache_ctrl = 0;
+   err = 0;
+   } else {
+   card->ext_csd.cache_ctrl = 1;
+   }
}
 
if (!oldcard)
-- 
1.7.0.4


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


[PATCH v2 2/2] mmc: core: Add claiming a host during mmc_cache_ctrl

2011-12-09 Thread Seungwon Jeon
While calling mmc_cache_ctrl() a host is not claimed. This patch
adds the mmc_try_claim_host() for quick response in suspend.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/core.c |8 +++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 83ac6e6..efdbf9d 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2359,7 +2359,13 @@ int mmc_suspend_host(struct mmc_host *host)
cancel_delayed_work(&host->disable);
cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
-   err = mmc_cache_ctrl(host, 0);
+   if (mmc_try_claim_host(host)) {
+   err = mmc_cache_ctrl(host, 0);
+   mmc_do_release_host(host);
+   } else {
+   err = -EBUSY;
+   }
+
if (err)
goto out;
 
-- 
1.7.0.4


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


RE: mmc: dw_mmc: Add more capabilities field

2011-12-12 Thread Seungwon Jeon
James Hogan wrote:
> On 9 December 2011 05:49, Seungwon Jeon  wrote:
> > Signed-off-by: Seungwon Jeon 
> 
> A commit message would be useful.
"This patch adds another capabilities field for MMC_CAPS2_XXX."
Is a commit message disappeared?
> 
> > ---
> >  drivers/mmc/host/dw_mmc.c  |    6 ++
> >  include/linux/mmc/dw_mmc.h |    1 +
> >  2 files changed, 7 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> > index 3aaeb08..366df6b 100644
> > --- a/drivers/mmc/host/dw_mmc.c
> > +++ b/drivers/mmc/host/dw_mmc.c
> > @@ -1681,6 +1681,12 @@ static int __init dw_mci_init_slot(struct dw_mci 
> > *host, unsigned int id)
> >        else
> >                mmc->caps = 0;
> >
> > +       if (host->pdata->caps2)
> > +               mmc->caps2 = host->pdata->caps2;
> > +       else
> > +               mmc->caps2 = 0;
> > +
> > +
> 
> There's really no need to check the value here, just copy it over.
> Same with the other caps field really.
Yes. No need to check.
It would be added rather than be copied.

Thanks,
Seungwon Jeon.
> 
> >        if (host->pdata->get_bus_wd)
> >                if (host->pdata->get_bus_wd(slot->id) >= 4)
> >                        mmc->caps |= MMC_CAP_4_BIT_DATA;
> > diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
> > index 6dc9b80..e8779c6 100644
> > --- a/include/linux/mmc/dw_mmc.h
> > +++ b/include/linux/mmc/dw_mmc.h
> > @@ -214,6 +214,7 @@ struct dw_mci_board {
> >        unsigned int bus_hz; /* Bus speed */
> >
> >        unsigned int caps;      /* Capabilities */
> > +       unsigned int caps2;     /* More capabilities */
> >        /*
> >         * Override fifo depth. If 0, autodetect it from the FIFOTH register,
> >         * but note that this may not be reliable after a bootloader has used
> > --
> > 1.7.0.4
> >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> > the body of a message to majord...@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> other than that it looks fine to me.
> 
> --
> James Hogan
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


[PATCH v2] mmc: dw_mmc: Add second capability field

2011-12-22 Thread Seungwon Jeon
This patch adds caps2 filed for second capability in dw_mmc.
It corresponds with MMC_CAPS2_XXX. And this patch removes the
unnecessary condition statement for assigning caps.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/host/dw_mmc.c  |6 ++
 include/linux/mmc/dw_mmc.h |1 +
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 3aaeb08..3f5a77a 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1676,10 +1676,8 @@ static int __init dw_mci_init_slot(struct dw_mci *host, 
unsigned int id)
if (host->pdata->setpower)
host->pdata->setpower(id, 0);
 
-   if (host->pdata->caps)
-   mmc->caps = host->pdata->caps;
-   else
-   mmc->caps = 0;
+   mmc->caps |= host->pdata->caps;
+   mmc->caps2 |= host->pdata->caps2;
 
if (host->pdata->get_bus_wd)
if (host->pdata->get_bus_wd(slot->id) >= 4)
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 6dc9b80..e8779c6 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -214,6 +214,7 @@ struct dw_mci_board {
unsigned int bus_hz; /* Bus speed */
 
unsigned int caps;  /* Capabilities */
+   unsigned int caps2; /* More capabilities */
/*
 * Override fifo depth. If 0, autodetect it from the FIFOTH register,
 * but note that this may not be reliable after a bootloader has used
-- 
1.7.0.4


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


[PATCH RESEND] mmc: dw_mmc: Support predefined mutiple block transfers

2011-12-22 Thread Seungwon Jeon
This patch adds the support for predefined multiple block r/w.
dw_mmc can support MMC_CAP_CMD23 capability.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/host/dw_mmc.c |   34 --
 1 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 3aaeb08..04653e8 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -588,11 +588,11 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
mci_writel(host, CTYPE, (slot->ctype << slot->id));
 }
 
-static void dw_mci_start_request(struct dw_mci *host,
-struct dw_mci_slot *slot)
+static void __dw_mci_start_request(struct dw_mci *host,
+  struct dw_mci_slot *slot,
+  struct mmc_command *cmd)
 {
struct mmc_request *mrq;
-   struct mmc_command *cmd;
struct mmc_data *data;
u32 cmdflags;
 
@@ -610,14 +610,13 @@ static void dw_mci_start_request(struct dw_mci *host,
host->completed_events = 0;
host->data_status = 0;
 
-   data = mrq->data;
+   data = cmd->data;
if (data) {
dw_mci_set_timeout(host);
mci_writel(host, BYTCNT, data->blksz*data->blocks);
mci_writel(host, BLKSIZ, data->blksz);
}
 
-   cmd = mrq->cmd;
cmdflags = dw_mci_prepare_command(slot->mmc, cmd);
 
/* this is the first command, send the initialization clock */
@@ -635,6 +634,16 @@ static void dw_mci_start_request(struct dw_mci *host,
host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop);
 }
 
+static void dw_mci_start_request(struct dw_mci *host,
+struct dw_mci_slot *slot)
+{
+   struct mmc_request *mrq = slot->mrq;
+   struct mmc_command *cmd;
+
+   cmd = mrq->sbc ? mrq->sbc : mrq->cmd;
+   __dw_mci_start_request(host, slot, cmd);
+}
+
 /* must be called with host->lock held */
 static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
 struct mmc_request *mrq)
@@ -889,7 +898,14 @@ static void dw_mci_tasklet_func(unsigned long priv)
cmd = host->cmd;
host->cmd = NULL;
set_bit(EVENT_CMD_COMPLETE, &host->completed_events);
-   dw_mci_command_complete(host, host->mrq->cmd);
+   dw_mci_command_complete(host, cmd);
+   if ((cmd == host->mrq->sbc) && !cmd->error) {
+   prev_state = state = STATE_SENDING_CMD;
+   __dw_mci_start_request(host, host->cur_slot,
+  host->mrq->cmd);
+   goto unlock;
+   }
+
if (!host->mrq->data || cmd->error) {
dw_mci_request_end(host, host->mrq);
goto unlock;
@@ -967,6 +983,12 @@ static void dw_mci_tasklet_func(unsigned long priv)
goto unlock;
}
 
+   if (host->mrq->sbc && !data->error) {
+   data->stop->error = 0;
+   dw_mci_request_end(host, host->mrq);
+   goto unlock;
+   }
+
prev_state = state = STATE_SENDING_STOP;
if (!data->error)
send_stop_cmd(host, data);
-- 
1.7.0.4


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


[PATCH v2 RESEND 0/2] mmc: core: Fix cache control for eMMC4.5

2011-12-26 Thread Seungwon Jeon
This patch-set fixed the cache control for eMMC4.5

Seungwon Jeon (2):
  mmc: core: Separate the timeout value for cache-ctrl
  mmc: core: Add claiming a host during mmc_cache_ctrl

 drivers/mmc/core/core.c |   29 +++--
 drivers/mmc/core/mmc.c  |   13 +++--
 2 files changed, 30 insertions(+), 12 deletions(-)

Best regards,
Seungwon Jeon.
--
1.7.2.3


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


[PATCH v2 RESEND 1/2] mmc: core: Separate the timeout value for cache-ctrl

2011-12-26 Thread Seungwon Jeon
Turning the cache off implies flushing cache which doesn't define
maximum timeout unlike cache-on. This patch will apply the generic
CMD6 timeout only for cache-on. Additionally the kernel message is
added for checking failure case of cache-on.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/core.c |   22 +-
 drivers/mmc/core/mmc.c  |   12 ++--
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index a2aa860..83ac6e6 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2315,6 +2315,7 @@ EXPORT_SYMBOL(mmc_flush_cache);
 int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
 {
struct mmc_card *card = host->card;
+   unsigned int timeout;
int err = 0;
 
if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) ||
@@ -2325,16 +2326,19 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
(card->ext_csd.cache_size > 0)) {
enable = !!enable;
 
-   if (card->ext_csd.cache_ctrl ^ enable)
+   if (card->ext_csd.cache_ctrl ^ enable) {
+   timeout = enable ? card->ext_csd.generic_cmd6_time : 0;
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-   EXT_CSD_CACHE_CTRL, enable, 0);
-   if (err)
-   pr_err("%s: cache %s error %d\n",
-   mmc_hostname(card->host),
-   enable ? "on" : "off",
-   err);
-   else
-   card->ext_csd.cache_ctrl = enable;
+   EXT_CSD_CACHE_CTRL, enable, timeout);
+
+   if (err)
+   pr_err("%s: cache %s error %d\n",
+   mmc_hostname(card->host),
+   enable ? "on" : "off",
+   err);
+   else
+   card->ext_csd.cache_ctrl = enable;
+   }
}
 
return err;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index f0a9f1f..403ad0e 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1077,14 +1077,22 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if ((host->caps2 & MMC_CAP2_CACHE_CTRL) &&
card->ext_csd.cache_size > 0) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-   EXT_CSD_CACHE_CTRL, 1, 0);
+   EXT_CSD_CACHE_CTRL, 1,
+   card->ext_csd.generic_cmd6_time);
if (err && err != -EBADMSG)
goto free_card;
 
/*
 * Only if no error, cache is turned on successfully.
 */
-   card->ext_csd.cache_ctrl = err ? 0 : 1;
+   if (err) {
+   pr_warning("%s: Cache is supported, "
+   "but failed to turn on (%d)\n",
+   mmc_hostname(card->host), err);
+   err = 0;
+   } else {
+   card->ext_csd.cache_ctrl = 1;
+   }
}
 
if (!oldcard)
-- 
1.7.0.4


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


[PATCH v2 RESEND 2/2] mmc: core: Add claiming a host during mmc_cache_ctrl

2011-12-26 Thread Seungwon Jeon
While calling mmc_cache_ctrl() a host is not claimed. This patch
adds the mmc_try_claim_host() for quick response in suspend.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/core/core.c |8 +++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 83ac6e6..efdbf9d 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2359,7 +2359,13 @@ int mmc_suspend_host(struct mmc_host *host)
cancel_delayed_work(&host->disable);
cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
-   err = mmc_cache_ctrl(host, 0);
+   if (mmc_try_claim_host(host)) {
+   err = mmc_cache_ctrl(host, 0);
+   mmc_do_release_host(host);
+   } else {
+   err = -EBUSY;
+   }
+
if (err)
goto out;
 
-- 
1.7.0.4


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


[PATCH] mmc: dw_mmc: Clear the DDR mode for non-DDR

2012-01-01 Thread Seungwon Jeon
UHS_REG should be cleared for non-DDR mode. But currently there is
no way to clear DDR mode, if it is already set once. This patch adds
clearing DDR mode for non-DDD mode.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/host/dw_mmc.c |   11 +++
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index c583b94..94e2238 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -707,12 +707,15 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
break;
}
 
+   regs = mci_readl(slot->host, UHS_REG);
+
/* DDR mode set */
-   if (ios->timing == MMC_TIMING_UHS_DDR50) {
-   regs = mci_readl(slot->host, UHS_REG);
+   if (ios->timing == MMC_TIMING_UHS_DDR50)
regs |= (0x1 << slot->id) << 16;
-   mci_writel(slot->host, UHS_REG, regs);
-   }
+   else
+   regs &= ~(0x1 << slot->id) << 16;
+
+   mci_writel(slot->host, UHS_REG, regs);
 
if (ios->clock) {
/*
-- 
1.7.0.4


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


[PATCH] mmc: dw_mmc: protect a sequence of request and request-done.

2011-06-20 Thread Seungwon Jeon
Response timeout(RTO), Response crc error(RCRC) and Response error(RE)
signals come with command done(CD) and can be raised preceding command
done(CD). That is these error interrupts and CD can be handled in
separate dw_mci_interrupt(). If mmc_request_done() is called because of
response timeout before command done is occured, next request can be
sent, but CD of current request is not finished. This can bring about
a broken sequence of request and request-done.

And Data error interrupt(DRTO, DCRC, SBE, EBE) and data transfer
over(DTO) are same reanson.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/host/dw_mmc.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 1ca830c..22be372 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1202,7 +1202,6 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
host->cmd_status = status;
smp_wmb();
set_bit(EVENT_CMD_COMPLETE, &host->pending_events);
-   tasklet_schedule(&host->tasklet);
}
 
if (pending & DW_MCI_DATA_ERROR_FLAGS) {
@@ -1211,7 +1210,9 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
host->data_status = status;
smp_wmb();
set_bit(EVENT_DATA_ERROR, &host->pending_events);
-   tasklet_schedule(&host->tasklet);
+   if (!(pending & (SDMMC_INT_DTO | SDMMC_INT_DCRC |
+SDMMC_INT_SBE | SDMMC_INT_EBE)))
+   tasklet_schedule(&host->tasklet);
}
 
if (pending & SDMMC_INT_DATA_OVER) {
-- 
1.7.1

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


[PATCH] mmc: dw_mmc: set the card_width bit per card.

2011-06-20 Thread Seungwon Jeon
This patch sets the card_width bit of CTYPE for the corresponding card.

CTYPE[31] and CTYPE[16] correspond respectively to card[15] and card[0]
for 8-bit mode. And CTYPE[15] and CTYPE[0] correspond respectively to
card[15] and CTYPE[0] for 1-bit or 4-bit mode.

Signed-off-by: Seungwon Jeon 
---
 drivers/mmc/host/dw_mmc.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 66dcddb..1ca830c 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -574,7 +574,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
}
 
/* Set the current slot bus width */
-   mci_writel(host, CTYPE, slot->ctype);
+   mci_writel(host, CTYPE, (slot->ctype << slot->id));
 }
 
 static void dw_mci_start_request(struct dw_mci *host,
-- 
1.7.1

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


[PATCH] ARM: EXYNOS4: Add platform device for dwmci driver.

2011-07-13 Thread Seungwon Jeon
This patch add platform devices for Synopsys DesignWare Multimedia Card
Interface driver.

Signed-off-by: Seungwon Jeon 
---
 arch/arm/mach-exynos4/Kconfig |5 ++
 arch/arm/mach-exynos4/Makefile|1 +
 arch/arm/mach-exynos4/dev-dwmci.c |   86 +
 arch/arm/mach-exynos4/include/mach/irqs.h |1 +
 arch/arm/mach-exynos4/include/mach/map.h  |1 +
 arch/arm/plat-samsung/include/plat/devs.h |1 +
 6 files changed, 95 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-exynos4/dev-dwmci.c

diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 5115b90..c82674a 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -35,6 +35,11 @@ config EXYNOS4_DEV_SYSMMU
help
  Common setup code for SYSTEM MMU in EXYNOS4
 
+config EXYNOS4_DEV_DWMCI
+   bool
+   help
+ Compile in platform device definitions for DWMCI
+
 config EXYNOS4_SETUP_I2C1
bool
help
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index 60fe5ec..eeeaada 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -43,6 +43,7 @@ obj-y += dev-audio.o
 obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
 obj-$(CONFIG_EXYNOS4_DEV_PD)   += dev-pd.o
 obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)   += dev-sysmmu.o
+obj-$(CONFIG_EXYNOS4_DEV_DWMCI)+= dev-dwmci.o
 
 obj-$(CONFIG_EXYNOS4_SETUP_FIMC)   += setup-fimc.o
 obj-$(CONFIG_EXYNOS4_SETUP_I2C1)   += setup-i2c1.o
diff --git a/arch/arm/mach-exynos4/dev-dwmci.c 
b/arch/arm/mach-exynos4/dev-dwmci.c
new file mode 100644
index 000..6b69707
--- /dev/null
+++ b/arch/arm/mach-exynos4/dev-dwmci.c
@@ -0,0 +1,86 @@
+/*
+ * linuxarch/arm/mach-exynos4/dev-dwmci.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Platform device for Synopsys DesignWare Mobile Storage IP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+static int exynos4_dwmci_init(u32 slot_id, irq_handler_t handler, void *data);
+static int exynos4_dwmci_get_ocr(u32 slot_id);
+static int exynos4_dwmci_get_bus_wd(u32 slot_id);
+
+static struct resource exynos4_dwmci_resource[] = {
+   [0] = {
+   .start = EXYNOS4_PA_DWMCI,
+   .end   = EXYNOS4_PA_DWMCI + SZ_4K - 1,
+   .flags = IORESOURCE_MEM,
+   },
+   [1] = {
+   .start = IRQ_DWMCI,
+   .end   = IRQ_DWMCI,
+   .flags = IORESOURCE_IRQ,
+   }
+};
+
+static struct dw_mci_board exynos4_dwci_pdata = {
+   .num_slots  = 1,
+   .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION,
+   .bus_hz = 80*1000*1000,
+   .detect_delay_ms= 200,
+   .init   = exynos4_dwmci_init,
+   .get_ocr= exynos4_dwmci_get_ocr,
+   .get_bus_wd = exynos4_dwmci_get_bus_wd,
+   .select_slot= NULL,
+};
+
+static u64 exynos4_dwmci_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos4_device_dwmci = {
+   .name   = "dw_mmc",
+   .id = -1,
+   .num_resources  = ARRAY_SIZE(exynos4_dwmci_resource),
+   .resource   = exynos4_dwmci_resource,
+   .dev= {
+   .dma_mask   = &exynos4_dwmci_dmamask,
+   .coherent_dma_mask  = DMA_BIT_MASK(32),
+   .platform_data  = &exynos4_dwci_pdata,
+   },
+};
+
+static int exynos4_dwmci_get_ocr(u32 slot_id)
+{
+   return MMC_VDD_32_33 | MMC_VDD_33_34;
+}
+
+static int exynos4_dwmci_get_bus_wd(u32 slot_id)
+{
+   return 4;
+}
+
+static int exynos4_dwmci_init(u32 slot_id, irq_handler_t handler, void *data)
+{
+   return 0;
+}
+
diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h 
b/arch/arm/mach-exynos4/include/mach/irqs.h
index 5d03730..b720246 100644
--- a/arch/arm/mach-exynos4/include/mach/irqs.h
+++ b/arch/arm/mach-exynos4/include/mach/irqs.h
@@ -107,6 +107,7 @@
 #define IRQ_HSMMC1 COMBINER_IRQ(29, 1)
 #define IRQ_HSMMC2 COMBINER_IRQ(29, 2)
 #define IRQ_HSMMC3 COMBINER_IRQ(29, 3)
+#define IRQ_DWMCI  COMBINER_IRQ(29, 4)
 
 #define IRQ_MIPI_CSIS0 COMBINER_IRQ(30, 0)
 #define IRQ_MIPI_CSIS1 COMBINER_IRQ(30, 1)
diff --git a/arch/arm/mach-exynos4/include/mach/map.h 
b/arch/arm/mach-exynos4/include/mach/map.h
index 0009e77..352e500 100644
--- a/arch/arm/ma

RE: [PATCH] ARM: EXYNOS4: Add platform device for dwmci driver.

2011-07-13 Thread Seungwon Jeon
Hi,

Kyungmin Park wrote:
> On Wed, Jul 13, 2011 at 4:17 PM, Seungwon Jeon 
> wrote:
> > This patch add platform devices for Synopsys DesignWare Multimedia Card
> > Interface driver.
> >
> > Signed-off-by: Seungwon Jeon 
> > ---
> >  arch/arm/mach-exynos4/Kconfig |5 ++
> >  arch/arm/mach-exynos4/Makefile|1 +
> >  arch/arm/mach-exynos4/dev-dwmci.c |   86
> +
> >  arch/arm/mach-exynos4/include/mach/irqs.h |1 +
> >  arch/arm/mach-exynos4/include/mach/map.h  |1 +
> >  arch/arm/plat-samsung/include/plat/devs.h |1 +
> >  6 files changed, 95 insertions(+), 0 deletions(-)
> >  create mode 100644 arch/arm/mach-exynos4/dev-dwmci.c
> >
> > diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-
> exynos4/Kconfig
> > index 5115b90..c82674a 100644
> > --- a/arch/arm/mach-exynos4/Kconfig
> > +++ b/arch/arm/mach-exynos4/Kconfig
> > @@ -35,6 +35,11 @@ config EXYNOS4_DEV_SYSMMU
> >help
> >  Common setup code for SYSTEM MMU in EXYNOS4
> >
> > +config EXYNOS4_DEV_DWMCI
> > +   bool
> > +   help
> > + Compile in platform device definitions for DWMCI
> > +
> >  config EXYNOS4_SETUP_I2C1
> >bool
> >help
> > diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-
> exynos4/Makefile
> > index 60fe5ec..eeeaada 100644
> > --- a/arch/arm/mach-exynos4/Makefile
> > +++ b/arch/arm/mach-exynos4/Makefile
> > @@ -43,6 +43,7 @@ obj-y += dev-audio.o
> >  obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
> >  obj-$(CONFIG_EXYNOS4_DEV_PD)   += dev-pd.o
> >  obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)   += dev-sysmmu.o
> > +obj-$(CONFIG_EXYNOS4_DEV_DWMCI)+= dev-dwmci.o
> >
> >  obj-$(CONFIG_EXYNOS4_SETUP_FIMC)   += setup-fimc.o
> >  obj-$(CONFIG_EXYNOS4_SETUP_I2C1)   += setup-i2c1.o
> > diff --git a/arch/arm/mach-exynos4/dev-dwmci.c b/arch/arm/mach-
> exynos4/dev-dwmci.c
> > new file mode 100644
> > index 000..6b69707
> > --- /dev/null
> > +++ b/arch/arm/mach-exynos4/dev-dwmci.c
> > @@ -0,0 +1,86 @@
> > +/*
> > + * linuxarch/arm/mach-exynos4/dev-dwmci.c
> > + *
> > + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> > + * http://www.samsung.com
> > + *
> > + * Platform device for Synopsys DesignWare Mobile Storage IP
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +
> > +static int exynos4_dwmci_init(u32 slot_id, irq_handler_t handler, void
> *data);
> > +static int exynos4_dwmci_get_ocr(u32 slot_id);
> > +static int exynos4_dwmci_get_bus_wd(u32 slot_id);
> No need to declare it at here.
> Just put the exynos4_dwci_pdata at last.

I'll apply your comment next.
Thank you.

> > +
> > +static struct resource exynos4_dwmci_resource[] = {
> > +   [0] = {
> > +   .start = EXYNOS4_PA_DWMCI,
> > +   .end   = EXYNOS4_PA_DWMCI + SZ_4K - 1,
> > +   .flags = IORESOURCE_MEM,
> > +   },
> > +   [1] = {
> > +   .start = IRQ_DWMCI,
> > +   .end   = IRQ_DWMCI,
> > +   .flags = IORESOURCE_IRQ,
> > +   }
> > +};
> > +
> > +static struct dw_mci_board exynos4_dwci_pdata = {
> > +   .num_slots  = 1,
> > +   .quirks = 
> > DW_MCI_QUIRK_BROKEN_CARD_DETECTION,
> > +   .bus_hz = 80*1000*1000,
> Does it correct value?
> > +   .detect_delay_ms= 200,
> > +   .init   = exynos4_dwmci_init,
> > +   .get_ocr= exynos4_dwmci_get_ocr,
> > +   .get_bus_wd = exynos4_dwmci_get_bus_wd,
> > +   .select_slot= NULL,
> > +};
> > +
> > +static u64 exynos4_dwmci_dmamask = DMA_BIT_MASK(32);
> > +
> > +struct platform_device exynos4_device_dwmci = {
> > +   .name   = "dw_mmc",

[PATCH v2] ARM: EXYNOS4: Add platform device for dwmci driver.

2011-07-14 Thread Seungwon Jeon
This patch add platform devices for Synopsys DesignWare Multimedia Card
Interface driver.

Signed-off-by: Seungwon Jeon 
---
 arch/arm/mach-exynos4/Kconfig |   12 
 arch/arm/mach-exynos4/Makefile|1 +
 arch/arm/mach-exynos4/dev-dwmci.c |   88 +
 arch/arm/mach-exynos4/include/mach/irqs.h |1 +
 arch/arm/mach-exynos4/include/mach/map.h  |1 +
 arch/arm/plat-samsung/include/plat/devs.h |1 +
 6 files changed, 104 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-exynos4/dev-dwmci.c

diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 5115b90..2ec5b96 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -35,6 +35,11 @@ config EXYNOS4_DEV_SYSMMU
help
  Common setup code for SYSTEM MMU in EXYNOS4
 
+config EXYNOS4_DEV_DWMCI
+   bool
+   help
+ Compile in platform device definitions for DWMCI
+
 config EXYNOS4_SETUP_I2C1
bool
help
@@ -200,6 +205,13 @@ comment "Configuration for HSMMC bus width"
 
 menu "Use 8-bit bus width"
 
+config EXYNOS4_DWMCI_8BIT
+   bool "DWMCI with 8-bit bus"
+   depends on EXYNOS4_DEV_DWMCI
+   help
+ Support DWMCI 8-bit bus.
+ If selected, Channel 1 is disabled.
+
 config EXYNOS4_SDHCI_CH0_8BIT
bool "Channel 0 with 8-bit bus"
help
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index 60fe5ec..eeeaada 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -43,6 +43,7 @@ obj-y += dev-audio.o
 obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
 obj-$(CONFIG_EXYNOS4_DEV_PD)   += dev-pd.o
 obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)   += dev-sysmmu.o
+obj-$(CONFIG_EXYNOS4_DEV_DWMCI)+= dev-dwmci.o
 
 obj-$(CONFIG_EXYNOS4_SETUP_FIMC)   += setup-fimc.o
 obj-$(CONFIG_EXYNOS4_SETUP_I2C1)   += setup-i2c1.o
diff --git a/arch/arm/mach-exynos4/dev-dwmci.c 
b/arch/arm/mach-exynos4/dev-dwmci.c
new file mode 100644
index 000..a0defa4
--- /dev/null
+++ b/arch/arm/mach-exynos4/dev-dwmci.c
@@ -0,0 +1,88 @@
+/*
+ * linuxarch/arm/mach-exynos4/dev-dwmci.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Platform device for Synopsys DesignWare Mobile Storage IP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+
+#ifdef EXYNOS4_DWMCI_8BIT
+#define BUS_WIDTH 8
+#else
+#define BUS_WIDTH 4
+#endif
+
+static int exynos4_dwmci_get_ocr(u32 slot_id)
+{
+   return MMC_VDD_32_33 | MMC_VDD_33_34;
+}
+
+static int exynos4_dwmci_get_bus_wd(u32 slot_id)
+{
+   return BUS_WIDTH;
+}
+
+static int exynos4_dwmci_init(u32 slot_id, irq_handler_t handler, void *data)
+{
+   return 0;
+}
+
+static struct resource exynos4_dwmci_resource[] = {
+   [0] = {
+   .start = EXYNOS4_PA_DWMCI,
+   .end   = EXYNOS4_PA_DWMCI + SZ_4K - 1,
+   .flags = IORESOURCE_MEM,
+   },
+   [1] = {
+   .start = IRQ_DWMCI,
+   .end   = IRQ_DWMCI,
+   .flags = IORESOURCE_IRQ,
+   }
+};
+
+static struct dw_mci_board exynos4_dwci_pdata = {
+   .num_slots  = 1,
+   .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION,
+   .bus_hz = 80*1000*1000,
+   .detect_delay_ms= 200,
+   .init   = exynos4_dwmci_init,
+   .get_ocr= exynos4_dwmci_get_ocr,
+   .get_bus_wd = exynos4_dwmci_get_bus_wd,
+   .select_slot= NULL,
+};
+
+static u64 exynos4_dwmci_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos4_device_dwmci = {
+   .name   = "dw_mmc",
+   .id = -1,
+   .num_resources  = ARRAY_SIZE(exynos4_dwmci_resource),
+   .resource   = exynos4_dwmci_resource,
+   .dev= {
+   .dma_mask   = &exynos4_dwmci_dmamask,
+   .coherent_dma_mask  = DMA_BIT_MASK(32),
+   .platform_data  = &exynos4_dwci_pdata,
+   },
+};
+
diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h 
b/arch/arm/mach-exynos4/include/mach/irqs.h
index 5d03730..b720246 100644
--- a/arch/arm/mach-exynos4/include/mach/irqs.h
+++ b/arch/arm/mach-exynos4/include/mach/irqs.h
@@ -107,6 +107,7 @@
 #define IRQ_HSMMC1 COMBINER_IRQ(29, 1)
 #define IRQ_HSMMC2 COMBINER_IRQ(29, 2)
 #define IRQ

RE: [PATCH v2] ARM: EXYNOS4: Add platform device for dwmci driver.

2011-07-14 Thread Seungwon Jeon
Hi,

Kyungmin Park wrote:
> On Thu, Jul 14, 2011 at 6:53 PM, Seungwon Jeon 
> wrote:
> > This patch add platform devices for Synopsys DesignWare Multimedia Card
> > Interface driver.
> >
> > Signed-off-by: Seungwon Jeon 
> > ---
> >  arch/arm/mach-exynos4/Kconfig |   12 
> >  arch/arm/mach-exynos4/Makefile|1 +
> >  arch/arm/mach-exynos4/dev-dwmci.c |   88
> +
> >  arch/arm/mach-exynos4/include/mach/irqs.h |1 +
> >  arch/arm/mach-exynos4/include/mach/map.h  |1 +
> >  arch/arm/plat-samsung/include/plat/devs.h |1 +
> >  6 files changed, 104 insertions(+), 0 deletions(-)
> >  create mode 100644 arch/arm/mach-exynos4/dev-dwmci.c
> >
> > diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-
> exynos4/Kconfig
> > index 5115b90..2ec5b96 100644
> > --- a/arch/arm/mach-exynos4/Kconfig
> > +++ b/arch/arm/mach-exynos4/Kconfig
> > @@ -35,6 +35,11 @@ config EXYNOS4_DEV_SYSMMU
> >help
> >  Common setup code for SYSTEM MMU in EXYNOS4
> >
> > +config EXYNOS4_DEV_DWMCI
> > +   bool
> > +   help
> > + Compile in platform device definitions for DWMCI
> > +
> >  config EXYNOS4_SETUP_I2C1
> >bool
> >help
> > @@ -200,6 +205,13 @@ comment "Configuration for HSMMC bus width"
> >
> >  menu "Use 8-bit bus width"
> >
> > +config EXYNOS4_DWMCI_8BIT
> > +   bool "DWMCI with 8-bit bus"
> > +   depends on EXYNOS4_DEV_DWMCI
> > +   help
> > + Support DWMCI 8-bit bus.
> > + If selected, Channel 1 is disabled.
> 
> No it should be determined at runtime instead of compile time.

Sorry for that I don't understand your meaning.
Perhaps, you want to decide the width according to the board type at runtime?
I expect the reason and description about your comment.
Bus width is board-specific information related with capability
which is not determined in runtime.
So we should decide and choice bus width considering the board target
before compiling.

Best regards,
Seungwon Jeon.

> 
> > +
> >  config EXYNOS4_SDHCI_CH0_8BIT
> >bool "Channel 0 with 8-bit bus"
> >help
> > diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-
> exynos4/Makefile
> > index 60fe5ec..eeeaada 100644
> > --- a/arch/arm/mach-exynos4/Makefile
> > +++ b/arch/arm/mach-exynos4/Makefile
> > @@ -43,6 +43,7 @@ obj-y += dev-audio.o
> >  obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
> >  obj-$(CONFIG_EXYNOS4_DEV_PD)   += dev-pd.o
> >  obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)   += dev-sysmmu.o
> > +obj-$(CONFIG_EXYNOS4_DEV_DWMCI)+= dev-dwmci.o
> >
> >  obj-$(CONFIG_EXYNOS4_SETUP_FIMC)   += setup-fimc.o
> >  obj-$(CONFIG_EXYNOS4_SETUP_I2C1)   += setup-i2c1.o
> > diff --git a/arch/arm/mach-exynos4/dev-dwmci.c b/arch/arm/mach-
> exynos4/dev-dwmci.c
> > new file mode 100644
> > index 000..a0defa4
> > --- /dev/null
> > +++ b/arch/arm/mach-exynos4/dev-dwmci.c
> > @@ -0,0 +1,88 @@
> > +/*
> > + * linuxarch/arm/mach-exynos4/dev-dwmci.c
> > + *
> > + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> > + * http://www.samsung.com
> > + *
> > + * Platform device for Synopsys DesignWare Mobile Storage IP
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +
> > +#ifdef EXYNOS4_DWMCI_8BIT
> > +#define BUS_WIDTH 8
> > +#else
> > +#define BUS_WIDTH 4
> > +#endif
> 
> Right, each board can modify the bus width. so it needs the helper
> function to setup.
> > +
> > +static int exynos4_dwmci_get_ocr(u32 slot_id)
> > +{
> > +   return MMC_VDD_32_33 | MMC_VDD_33_34;
> > +}
> > +
> > +static int exynos4_dwmci_get_bus_wd(u32 slot_id)
> > +{
> > +   return BUS_WIDTH;
> > +}
> > +
> > +static int exynos4_dwmci_init(u32 slot_id, irq_handler_t handler, void
> *data)
> > +{
> 

RE: [PATCH v2] ARM: EXYNOS4: Add platform device for dwmci driver.

2011-07-15 Thread Seungwon Jeon
Hi

Kyungmin Park wrote:
> On Fri, Jul 15, 2011 at 3:58 PM, Seungwon Jeon 
> wrote:
> > Hi,
> >
> > Kyungmin Park wrote:
> >> On Thu, Jul 14, 2011 at 6:53 PM, Seungwon Jeon 
> >> wrote:
> >> > This patch add platform devices for Synopsys DesignWare Multimedia
> Card
> >> > Interface driver.
> >> >
> >> > Signed-off-by: Seungwon Jeon 
> >> > ---
> >> >  arch/arm/mach-exynos4/Kconfig |   12 
> >> >  arch/arm/mach-exynos4/Makefile|1 +
> >> >  arch/arm/mach-exynos4/dev-dwmci.c |   88
> >> +
> >> >  arch/arm/mach-exynos4/include/mach/irqs.h |1 +
> >> >  arch/arm/mach-exynos4/include/mach/map.h  |1 +
> >> >  arch/arm/plat-samsung/include/plat/devs.h |1 +
> >> >  6 files changed, 104 insertions(+), 0 deletions(-)
> >> >  create mode 100644 arch/arm/mach-exynos4/dev-dwmci.c
> >> >
> >> > diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-
> >> exynos4/Kconfig
> >> > index 5115b90..2ec5b96 100644
> >> > --- a/arch/arm/mach-exynos4/Kconfig
> >> > +++ b/arch/arm/mach-exynos4/Kconfig
> >> > @@ -35,6 +35,11 @@ config EXYNOS4_DEV_SYSMMU
> >> >help
> >> >  Common setup code for SYSTEM MMU in EXYNOS4
> >> >
> >> > +config EXYNOS4_DEV_DWMCI
> >> > +   bool
> >> > +   help
> >> > + Compile in platform device definitions for DWMCI
> >> > +
> >> >  config EXYNOS4_SETUP_I2C1
> >> >bool
> >> >help
> >> > @@ -200,6 +205,13 @@ comment "Configuration for HSMMC bus width"
> >> >
> >> >  menu "Use 8-bit bus width"
> >> >
> >> > +config EXYNOS4_DWMCI_8BIT
> >> > +   bool "DWMCI with 8-bit bus"
> >> > +   depends on EXYNOS4_DEV_DWMCI
> >> > +   help
> >> > + Support DWMCI 8-bit bus.
> >> > + If selected, Channel 1 is disabled.
> >>
> >> No it should be determined at runtime instead of compile time.
> >
> > Sorry for that I don't understand your meaning.
> > Perhaps, you want to decide the width according to the board type at
> runtime?
> > I expect the reason and description about your comment.
> > Bus width is board-specific information related with capability
> > which is not determined in runtime.
> > So we should decide and choice bus width considering the board target
> > before compiling.
> It prohibit to make a single kernel as other platform does.
> As you know, now we can select multiple board support at exynos4.
> some board want to use 4-bit, other board want to use 8-bit. then how
> to select proper bus width?

Right, it can't be satisfied in single kernel image. 
But device driver seems not to be bothered about value of get_bus_wd().
If value is more than four, it doesn't matter whether 4 or 8.
I'll remove the configuration option.
Thank you.

> 
> >
> > Best regards,
> > Seungwon Jeon.
> >
> >>
> >> > +
> >> >  config EXYNOS4_SDHCI_CH0_8BIT
> >> >bool "Channel 0 with 8-bit bus"
> >> >help
> >> > diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-
> >> exynos4/Makefile
> >> > index 60fe5ec..eeeaada 100644
> >> > --- a/arch/arm/mach-exynos4/Makefile
> >> > +++ b/arch/arm/mach-exynos4/Makefile
> >> > @@ -43,6 +43,7 @@ obj-y += dev-audio.o
> >> >  obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
> >> >  obj-$(CONFIG_EXYNOS4_DEV_PD)   += dev-pd.o
> >> >  obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)   += dev-sysmmu.o
> >> > +obj-$(CONFIG_EXYNOS4_DEV_DWMCI)+= dev-dwmci.o
> >> >
> >> >  obj-$(CONFIG_EXYNOS4_SETUP_FIMC)   += setup-fimc.o
> >> >  obj-$(CONFIG_EXYNOS4_SETUP_I2C1)   += setup-i2c1.o
> >> > diff --git a/arch/arm/mach-exynos4/dev-dwmci.c b/arch/arm/mach-
> >> exynos4/dev-dwmci.c
> >> > new file mode 100644
> >> > index 000..a0defa4
> >> > --- /dev/null
> >> > +++ b/arch/arm/mach-exynos4/dev-dwmci.c
> >> > @@ -0,0 +1,88 @@
> >> > +/*
> >> > + * linuxarch/arm/mach-exynos4/dev-dwmci.c
> >> > + *
> >> > + * Copyright (c) 2011 Samsung Elect

[PATCH v3] ARM: EXYNOS4: Add platform device for dwmci driver.

2011-07-19 Thread Seungwon Jeon
This patch adds platform device for Synopsys DesignWare Multimedia Card
Interface driver.

Signed-off-by: Seungwon Jeon 
---
 arch/arm/mach-exynos4/Kconfig  |5 ++
 arch/arm/mach-exynos4/Makefile |1 +
 arch/arm/mach-exynos4/dev-dwmci.c  |   82 
 arch/arm/mach-exynos4/include/mach/dwmci.h |   20 +++
 arch/arm/mach-exynos4/include/mach/irqs.h  |1 +
 arch/arm/mach-exynos4/include/mach/map.h   |1 +
 arch/arm/plat-samsung/include/plat/devs.h  |1 +
 7 files changed, 111 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-exynos4/dev-dwmci.c
 create mode 100644 arch/arm/mach-exynos4/include/mach/dwmci.h

diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index a4fb109..31f798c 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -36,6 +36,11 @@ config EXYNOS4_DEV_SYSMMU
help
  Common setup code for SYSTEM MMU in EXYNOS4

+config EXYNOS4_DEV_DWMCI
+   bool
+   help
+ Compile in platform device definitions for DWMCI
+
 config EXYNOS4_SETUP_I2C1
bool
help
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index c3c70ab..4c4ea6b 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -38,6 +38,7 @@ obj-y += dev-audio.o
 obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
 obj-$(CONFIG_EXYNOS4_DEV_PD)   += dev-pd.o
 obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)   += dev-sysmmu.o
+obj-$(CONFIG_EXYNOS4_DEV_DWMCI)+= dev-dwmci.o

 obj-$(CONFIG_EXYNOS4_SETUP_FIMC)   += setup-fimc.o
 obj-$(CONFIG_EXYNOS4_SETUP_I2C1)   += setup-i2c1.o
diff --git a/arch/arm/mach-exynos4/dev-dwmci.c 
b/arch/arm/mach-exynos4/dev-dwmci.c
new file mode 100644
index 000..b025db4
--- /dev/null
+++ b/arch/arm/mach-exynos4/dev-dwmci.c
@@ -0,0 +1,82 @@
+/*
+ * linux/arch/arm/mach-exynos4/dev-dwmci.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Platform device for Synopsys DesignWare Mobile Storage IP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+
+static int exynos4_dwmci_get_bus_wd(u32 slot_id)
+{
+   return 4;
+}
+
+static int exynos4_dwmci_init(u32 slot_id, irq_handler_t handler, void *data)
+{
+   return 0;
+}
+
+static struct resource exynos4_dwmci_resource[] = {
+   [0] = {
+   .start  = EXYNOS4_PA_DWMCI,
+   .end= EXYNOS4_PA_DWMCI + SZ_4K - 1,
+   .flags  = IORESOURCE_MEM,
+   },
+   [1] = {
+   .start  = IRQ_DWMCI,
+   .end= IRQ_DWMCI,
+   .flags  = IORESOURCE_IRQ,
+   }
+};
+
+static struct dw_mci_board exynos4_dwci_pdata = {
+   .num_slots  = 1,
+   .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION,
+   .bus_hz = 80 * 1000 * 1000,
+   .detect_delay_ms= 200,
+   .init   = exynos4_dwmci_init,
+   .get_bus_wd = exynos4_dwmci_get_bus_wd,
+};
+
+static u64 exynos4_dwmci_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos4_device_dwmci = {
+   .name   = "dw_mmc",
+   .id = -1,
+   .num_resources  = ARRAY_SIZE(exynos4_dwmci_resource),
+   .resource   = exynos4_dwmci_resource,
+   .dev= {
+   .dma_mask   = &exynos4_dwmci_dmamask,
+   .coherent_dma_mask  = DMA_BIT_MASK(32),
+   .platform_data  = &exynos4_dwci_pdata,
+   },
+};
+
+void __init exynos4_dwmci_set_platdata(struct dw_mci_board *pd)
+{
+   struct dw_mci_board *npd;
+
+   npd = s3c_set_platdata(pd, sizeof(struct dw_mci_board),
+   &exynos4_device_dwmci);
+
+   if (!npd->init)
+   npd->init = exynos4_dwmci_init;
+   if (!npd->get_bus_wd)
+   npd->get_bus_wd = exynos4_dwmci_get_bus_wd;
+}
diff --git a/arch/arm/mach-exynos4/include/mach/dwmci.h 
b/arch/arm/mach-exynos4/include/mach/dwmci.h
new file mode 100644
index 000..7ce6574
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/dwmci.h
@@ -0,0 +1,20 @@
+/* linux/arch/arm/mach-exynos4/include/mach/dwmci.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Synopsys DesignWare Mobile Storage for EXYNOS4210
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free So

RE: [PATCH 2/2] mmc: dw_mmc: Handle wp-gpios from device tree

2012-11-22 Thread Seungwon Jeon
Hi,

wp-gpios has been implemented in dw_mmc-exynos.c
It can be reused for EXYNOS platform? We need to modify some though.

Thanks,
Seungwon Jeon

On Thursday, November 22, 2012, Doug Anderson  wrote:
> On some SoCs (like exynos5250) you need to use an external GPIO for
> write protect.  Add support for wp-gpios to the core dw_mmc driver
> since it could be useful across multiple SoCs.
> 
> With this change I am able to make use of the write protect for the
> external SD slot on exynos5250-snow.
> 
> Signed-off-by: Doug Anderson 
> ---
>  drivers/mmc/host/dw_mmc.c |   35 +++
>  1 files changed, 35 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 5b41348..9c79870 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -34,6 +34,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
> 
>  #include "dw_mmc.h"
> 
> @@ -74,6 +75,7 @@ struct idmac_desc {
>   * struct dw_mci_slot - MMC slot state
>   * @mmc: The mmc_host representing this slot.
>   * @host: The MMC controller this slot is using.
> + * @wp_gpio: If gpio_is_valid() we'll use this to read write protect.
>   * @ctype: Card type for this slot.
>   * @mrq: mmc_request currently being processed or waiting to be
>   *   processed, or NULL when the slot is idle.
> @@ -88,6 +90,8 @@ struct dw_mci_slot {
>   struct mmc_host *mmc;
>   struct dw_mci   *host;
> 
> + int wp_gpio;
> +
>   u32 ctype;
> 
>   struct mmc_request  *mrq;
> @@ -832,6 +836,8 @@ static int dw_mci_get_ro(struct mmc_host *mmc)
>   read_only = 0;
>   else if (brd->get_ro)
>   read_only = brd->get_ro(slot->id);
> + else if (gpio_is_valid(slot->wp_gpio))
> + read_only = gpio_get_value(slot->wp_gpio);
>   else
>   read_only =
>   mci_readl(slot->host, WRTPRT) & (1 << slot->id) ? 1 : 0;
> @@ -1802,6 +1808,29 @@ static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 
> slot)
>  " as 1\n");
>   return bus_wd;
>  }
> +
> +/* find the write protect gpio for a given slot; or -1 if none specified */
> +static u32 dw_mci_of_get_wp_gpio(struct device *dev, u8 slot)
> +{
> + struct device_node *np = dw_mci_of_find_slot_node(dev, slot);
> + int gpio;
> +
> + if (!np)
> + return -1;
> +
> + gpio = of_get_named_gpio(np, "wp-gpios", 0);
> +
> + /* Having a missing entry is valid; return silently */
> + if (!gpio_is_valid(gpio))
> + return -1;
> +
> + if (devm_gpio_request(dev, gpio, "dw-mci-wp")) {
> + dev_warn(dev, "gpio [%d] request failed\n", gpio);
> + return -1;
> + }
> +
> + return gpio;
> +}
>  #else /* CONFIG_OF */
>  static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot)
>  {
> @@ -1811,6 +1840,10 @@ static struct device_node 
> *dw_mci_of_find_slot_node(struct device *dev, u8 slot)
>  {
>   return NULL;
>  }
> +static u32 dw_mci_of_get_wp_gpio(struct device *dev, u8 slot)
> +{
> + return -1;
> +}
>  #endif /* CONFIG_OF */
> 
>  static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
> @@ -1923,6 +1956,8 @@ static int dw_mci_init_slot(struct dw_mci *host, 
> unsigned int id)
>   else
>   clear_bit(DW_MMC_CARD_PRESENT, &slot->flags);
> 
> + slot->wp_gpio = dw_mci_of_get_wp_gpio(host->dev, slot->id);
> +
>   mmc_add_host(mmc);
> 
>  #if defined(CONFIG_DEBUG_FS)
> --
> 1.7.7.3

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


RE: [PATCH 2/2] mmc: dw_mmc: Handle wp-gpios from device tree

2012-11-22 Thread Seungwon Jeon
On Thursday, November 22, 2012, Doug Anderson  wrote:
> On Wed, Nov 21, 2012 at 5:42 PM, Seungwon Jeon  wrote:
> > Hi,
> >
> > wp-gpios has been implemented in dw_mmc-exynos.c
> > It can be reused for EXYNOS platform? We need to modify some though.
> 
> Yup, I've seen that.  Patch 1/2 ("mmc: dw_mmc: exynos: Stop claiming
> wp-gpio") addressed that.  For some reason I can't find that on
> LKML.org yet.  Strange.  :-/  I'll forward it on to you shortly.
> 
> In any case: I found that the exynos code didn't actually work.  It
> claimed the GPIO but didn't ever look at it.
> 
> I have the beginnings of the code to implement this properly in the
> exynos code but I stopped working on it when I decided that other SoCs
> could also benefit from the code and it fit better in the general
> dw_mmc driver.
> 
> If you disagree and would like me to cleanup the version of this patch
> that's just in the exynos driver and post that, I will.  Just let me
> know.
Yes, origin code of dw_mmc-exynos didn't work fine. We need to modify it.
Anyway, some problem in mailing? I didn't get 1/2 of patch.
In addition, it's not found in any mail-archive. After resolved, I can review.

Thanks, 
Seungwon Jeon
> 
> 
> Thanks for the review!
> 
> -Doug

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


RE: [PATCH] ARM: Exynos: Remove unused non-dt support for dwmci controller

2012-11-26 Thread Seungwon Jeon
On Monday, November 26, 2012, Thomas Abraham  wrote:
> With device tree support enabled for dwmci controller, the unused non-dt 
> support
> for dwmci controller can be removed.
> 
> Signed-off-by: Thomas Abraham 
> ---
>  arch/arm/mach-exynos/Makefile |1 -
>  arch/arm/mach-exynos/dev-dwmci.c  |   75 
> -
>  arch/arm/mach-exynos/include/mach/dwmci.h |   20 
>  3 files changed, 0 insertions(+), 96 deletions(-)
>  delete mode 100644 arch/arm/mach-exynos/dev-dwmci.c
>  delete mode 100644 arch/arm/mach-exynos/include/mach/dwmci.h

Hi Thomas,

The following parts are remained. Also, no used code.
Could you check it?

./plat-samsung/include/plat/devs.h:126:extern struct platform_device 
exynos4_device_dwmci;
./Kconfig:111:config EXYNOS4_DEV_DWMCI

Thanks,
Seungwon Jeon

> 
> diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
> index c12ed6a..b189881 100644
> --- a/arch/arm/mach-exynos/Makefile
> +++ b/arch/arm/mach-exynos/Makefile
> @@ -50,7 +50,6 @@ obj-$(CONFIG_MACH_EXYNOS5_DT)   += 
> mach-exynos5-dt.o
>  obj-y+= dev-uart.o
>  obj-$(CONFIG_ARCH_EXYNOS4)   += dev-audio.o
>  obj-$(CONFIG_EXYNOS4_DEV_AHCI)   += dev-ahci.o
> -obj-$(CONFIG_EXYNOS4_DEV_DWMCI)  += dev-dwmci.o
>  obj-$(CONFIG_EXYNOS_DEV_DMA) += dma.o
>  obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI)   += dev-ohci.o
>  obj-$(CONFIG_EXYNOS_DEV_SYSMMU)  += dev-sysmmu.o
> diff --git a/arch/arm/mach-exynos/dev-dwmci.c 
> b/arch/arm/mach-exynos/dev-dwmci.c
> deleted file mode 100644
> index 7903501..000
> --- a/arch/arm/mach-exynos/dev-dwmci.c
> +++ /dev/null
> @@ -1,75 +0,0 @@
> -/*
> - * linux/arch/arm/mach-exynos4/dev-dwmci.c
> - *
> - * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> - *   http://www.samsung.com
> - *
> - * Platform device for Synopsys DesignWare Mobile Storage IP
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
> - */
> -
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -
> -#include 
> -
> -#include 
> -
> -static int exynos4_dwmci_get_bus_wd(u32 slot_id)
> -{
> - return 4;
> -}
> -
> -static int exynos4_dwmci_init(u32 slot_id, irq_handler_t handler, void *data)
> -{
> - return 0;
> -}
> -
> -static struct resource exynos4_dwmci_resource[] = {
> - [0] = DEFINE_RES_MEM(EXYNOS4_PA_DWMCI, SZ_4K),
> - [1] = DEFINE_RES_IRQ(EXYNOS4_IRQ_DWMCI),
> -};
> -
> -static struct dw_mci_board exynos4_dwci_pdata = {
> - .num_slots  = 1,
> - .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION,
> - .bus_hz = 80 * 1000 * 1000,
> - .detect_delay_ms= 200,
> - .init   = exynos4_dwmci_init,
> - .get_bus_wd = exynos4_dwmci_get_bus_wd,
> -};
> -
> -static u64 exynos4_dwmci_dmamask = DMA_BIT_MASK(32);
> -
> -struct platform_device exynos4_device_dwmci = {
> - .name   = "dw_mmc",
> - .id = -1,
> - .num_resources  = ARRAY_SIZE(exynos4_dwmci_resource),
> - .resource   = exynos4_dwmci_resource,
> - .dev= {
> - .dma_mask   = &exynos4_dwmci_dmamask,
> - .coherent_dma_mask  = DMA_BIT_MASK(32),
> - .platform_data  = &exynos4_dwci_pdata,
> - },
> -};
> -
> -void __init exynos4_dwmci_set_platdata(struct dw_mci_board *pd)
> -{
> - struct dw_mci_board *npd;
> -
> - npd = s3c_set_platdata(pd, sizeof(struct dw_mci_board),
> - &exynos4_device_dwmci);
> -
> - if (!npd->init)
> - npd->init = exynos4_dwmci_init;
> - if (!npd->get_bus_wd)
> - npd->get_bus_wd = exynos4_dwmci_get_bus_wd;
> -}
> diff --git a/arch/arm/mach-exynos/include/mach/dwmci.h 
> b/arch/arm/mach-exynos/include/mach/dwmci.h
> deleted file mode 100644
> index 7ce6574..000
> --- a/arch/arm/mach-exynos/include/mach/dwmci.h
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -/* linux/arch/arm/mach-exynos4/include/mach/dwmci.h
> - *
> - * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> - *   http://www.samsung.com/
> - *
> - * Synopsys DesignWare Mobile Storage for EXYNOS4210
> - *
> - * This program is free software; you can redistribute it and/or modif

RE: [PATCH v2 1/2] mmc: dw_mmc: exynos: Stop claiming wp-gpio

2012-11-28 Thread Seungwon Jeon
Yes. pin of write protection is common property.
This change is good. I have some suggestion below.
Could you check it?

On Friday, November 23, 2012, Doug Anderson wrote:
> The exynos code claimed wp-gpio with devm_gpio_request() but never did
> anything with it.  That meant that anyone using a write protect GPIO
> would effectively be write protected all the time.
> 
> A future change will move the wp-gpio support to the core dw_mmc.c
> file.  Now the exynos-specific code won't claim the GPIO but will
> just set the DW_MCI_QUIRK_NO_WRITE_PROTECT quirk if write protect
> won't be used.
> 
> Signed-off-by: Doug Anderson 
> 
> ---
> Changes in v2:
> - Nothing new in this patch
> 
>  drivers/mmc/host/dw_mmc-exynos.c |   12 ++--
>  1 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mmc/host/dw_mmc-exynos.c 
> b/drivers/mmc/host/dw_mmc-exynos.c
> index 4d50da6..58cc03e 100644
> --- a/drivers/mmc/host/dw_mmc-exynos.c
> +++ b/drivers/mmc/host/dw_mmc-exynos.c
> @@ -175,12 +175,12 @@ static int dw_mci_exynos_setup_bus(struct dw_mci *host,
>   }
>   }
> 
> - gpio = of_get_named_gpio(slot_np, "wp-gpios", 0);
> - if (gpio_is_valid(gpio)) {
> - if (devm_gpio_request(host->dev, gpio, "dw-mci-wp"))
> - dev_info(host->dev, "gpio [%d] request failed\n",
> - gpio);
> - } else {
> + /*
> +  * If there are no write-protect GPIOs present then we assume no write
> +  * protect.  The mci_readl() in dw_mmc.c won't work since it's not
> +  * hooked up on exynos.
> +  */
> + if (!of_find_property(slot_np, "wp-gpios", NULL)) {
>   dev_info(host->dev, "wp gpio not available");
>   host->pdata->quirks |= DW_MCI_QUIRK_NO_WRITE_PROTECT;
>   }
All card types need this quirk in case wp-gpio property is empty?
I think wp-pin is valid for SD card, not eMMC/SDIO.
Of course, I know origin code did it.
How about removing whole checking routine?
Instead, new definition for this quirk can be added into 
'dw_mci_of_quirks'(dw_mmc.c) and dts file.

Thanks,
Seungwon Jeon
> --
> 1.7.7.3

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


RE: [PATCH v2 1/2] mmc: dw_mmc: exynos: Stop claiming wp-gpio

2012-11-28 Thread Seungwon Jeon
Hi Doug,

On Thursday, November 29, 2012, Doug Anderson wrote:
> Seungwon,
> 
> Thanks for the review.  See below for comments.  If you'd like me to
> respin then please let me know.  Otherwise I look forward to your ack.
> 
> On Wed, Nov 28, 2012 at 1:29 AM, Seungwon Jeon  wrote:
> > Yes. pin of write protection is common property.
> > This change is good. I have some suggestion below.
> > Could you check it?
> >
> > On Friday, November 23, 2012, Doug Anderson wrote:
> >> The exynos code claimed wp-gpio with devm_gpio_request() but never did
> >> anything with it.  That meant that anyone using a write protect GPIO
> >> would effectively be write protected all the time.
> >>
> >> A future change will move the wp-gpio support to the core dw_mmc.c
> >> file.  Now the exynos-specific code won't claim the GPIO but will
> >> just set the DW_MCI_QUIRK_NO_WRITE_PROTECT quirk if write protect
> >> won't be used.
> >>
> >> Signed-off-by: Doug Anderson 
> >>
> >> ---
> >> Changes in v2:
> >> - Nothing new in this patch
> >>
> >>  drivers/mmc/host/dw_mmc-exynos.c |   12 ++--
> >>  1 files changed, 6 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/drivers/mmc/host/dw_mmc-exynos.c 
> >> b/drivers/mmc/host/dw_mmc-exynos.c
> >> index 4d50da6..58cc03e 100644
> >> --- a/drivers/mmc/host/dw_mmc-exynos.c
> >> +++ b/drivers/mmc/host/dw_mmc-exynos.c
> >> @@ -175,12 +175,12 @@ static int dw_mci_exynos_setup_bus(struct dw_mci 
> >> *host,
> >>   }
> >>   }
> >>
> >> - gpio = of_get_named_gpio(slot_np, "wp-gpios", 0);
> >> - if (gpio_is_valid(gpio)) {
> >> - if (devm_gpio_request(host->dev, gpio, "dw-mci-wp"))
> >> - dev_info(host->dev, "gpio [%d] request failed\n",
> >> - gpio);
> >> - } else {
> >> + /*
> >> +  * If there are no write-protect GPIOs present then we assume no 
> >> write
> >> +  * protect.  The mci_readl() in dw_mmc.c won't work since it's not
> >> +  * hooked up on exynos.
> >> +  */
> >> + if (!of_find_property(slot_np, "wp-gpios", NULL)) {
> >>   dev_info(host->dev, "wp gpio not available");
> >>   host->pdata->quirks |= DW_MCI_QUIRK_NO_WRITE_PROTECT;
> >>   }
> > All card types need this quirk in case wp-gpio property is empty?
> > I think wp-pin is valid for SD card, not eMMC/SDIO.
> 
> Right.  It is only checked right now by the SD code (mmc/core/sd.c).
> It doesn't particularly hurt to set it the quirk in other cases though
> and it seems nice not to add special cases.  I could imagine someone
> extending the MMC code at some point to support write protect (via
> GPIO) for eMMC, so there's even a slight justification for avoiding
> the special case.
> 
> 
> > Of course, I know origin code did it.
> > How about removing whole checking routine?
> > Instead, new definition for this quirk can be added into 
> > 'dw_mci_of_quirks'(dw_mmc.c) and dts file.
> 
> On _exynos_ all SD cards need this quirk if there is no wp-gpio
> property.  However this is not generally true for all users of dw_mmc.
>  The DesignWare IP Block actually has a write protect input that can
> be read with "mci_readl(slot->host, WRTPRT)" but on exynos the
> DesignWare write protect line isn't exposed on any physical pins.
> That means that the only possible way to do write protect on exynos is
> using a GPIO.
> 
> The above means that on exynos if the GPIO isn't defined we will
> assume no write protect.  On other platforms if the GPIO isn't defined
> we'll assume that the "mci_readl" will work and we'll use that.
> 
> If people would prefer it I can code up an alternate solution that
> doesn't touch any exynos code but that would introduce a new device
> tree binding.  We could accomplish what's needed for exynos using a
> property like "broken-internal-wp".
> 
> Please let me know if you'd like me to submit a new patch with this
> solution or if you like the existing solution.
> 
Write protect is additional interface related with SD socket. 
WP switch appears in SD standard size card. 
In case EMMC/SDIO spec, there is no mentions about this WP pin.
As you mentioned above, that's why 'ger_ro' is called only in sd

RE: [PATCH v3 1/4] mmc: dw_mmc: Add "disable-wp" device tree property

2012-11-30 Thread Seungwon Jeon
Doug, Thanks to work.
Looks good to me with other patches.

Acked-by: Seungwon Jeon 

On Friday, November 30, 2012, Doug Anderson wrote:
> The "disable-wp" property is used to specify that a given SD card slot
> doesn't have a concept of write protect.  This eliminates the need for
> special case code for SD slots that should never be write protected
> (like a micro SD slot or a dev board).
> 
> The dw_mmc driver is special in needing to specify "disable-wp"
> because the lack of a "wp-gpios" property means to use the special
> purpose write protect line.  On some other mmc devices the lack of
> "wp-gpios" means that write protect should be disabled.
> 
> Signed-off-by: Doug Anderson 
> ---
> Changes in v3:
> - New for this version of the patch series.  Chose "disable-wp" rather
>   than the discussed "broken-internal-wp" since it mapped more cleanly
>   to an existing quirk (and the only reason to specify that the
>   internal wp is broken is if you're disabling the write protect
>   anyway).
> 
>  .../devicetree/bindings/mmc/synopsis-dw-mshc.txt   |   12 +-
>  drivers/mmc/host/dw_mmc.c  |   36 
> +++-
>  include/linux/mmc/dw_mmc.h |4 ++
>  3 files changed, 49 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
> b/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
> index 06cd32d08..726fd21 100644
> --- a/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
> +++ b/Documentation/devicetree/bindings/mmc/synopsis-dw-mshc.txt
> @@ -26,8 +26,16 @@ Required Properties:
>   * bus-width: as documented in mmc core bindings.
> 
>   * wp-gpios: specifies the write protect gpio line. The format of the
> -   gpio specifier depends on the gpio controller. If the write-protect
> -   line is not available, this property is optional.
> +   gpio specifier depends on the gpio controller. If a GPIO is not used
> +   for write-protect, this property is optional.
> +
> + * disable-wp: If the wp-gpios property isn't present then (by default)
> +   we'd assume that the write protect is hooked up directly to the
> +   controller's special purpose write protect line (accessible via
> +   the WRTPRT register).  However, it's possible that we simply don't
> +   want write protect.  In that case specify 'disable-wp'.
> +   NOTE: This property is not required for slots known to always
> +   connect to eMMC or SDIO cards.
> 
>  Optional properties:
> 
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 7342029..b47b1e9 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -74,6 +74,7 @@ struct idmac_desc {
>   * struct dw_mci_slot - MMC slot state
>   * @mmc: The mmc_host representing this slot.
>   * @host: The MMC controller this slot is using.
> + * @quirks: Slot-level quirks (DW_MCI_SLOT_QUIRK_XXX)
>   * @ctype: Card type for this slot.
>   * @mrq: mmc_request currently being processed or waiting to be
>   *   processed, or NULL when the slot is idle.
> @@ -88,6 +89,8 @@ struct dw_mci_slot {
>   struct mmc_host *mmc;
>   struct dw_mci   *host;
> 
> + int quirks;
> +
>   u32 ctype;
> 
>   struct mmc_request  *mrq;
> @@ -828,7 +831,8 @@ static int dw_mci_get_ro(struct mmc_host *mmc)
>   struct dw_mci_board *brd = slot->host->pdata;
> 
>   /* Use platform get_ro function, else try on board write protect */
> - if (brd->quirks & DW_MCI_QUIRK_NO_WRITE_PROTECT)
> + if ((brd->quirks & DW_MCI_QUIRK_NO_WRITE_PROTECT) ||
> + (slot->quirks & DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT))
>   read_only = 0;
>   else if (brd->get_ro)
>   read_only = brd->get_ro(slot->id);
> @@ -1788,6 +1792,30 @@ static struct device_node 
> *dw_mci_of_find_slot_node(struct device *dev, u8 slot)
>   return NULL;
>  }
> 
> +static struct dw_mci_of_slot_quirks {
> + char *quirk;
> + int id;
> +} of_slot_quirks[] = {
> + {
> + .quirk  = "disable-wp",
> + .id = DW_MCI_SLOT_QUIRK_NO_WRITE_PROTECT,
> + },
> +};
> +
> +static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot)
> +{
> + struct device_node *np = dw_mci_of_find_slot_node(dev, slot);
> + int quirks = 0;
> + int idx;
> +
> + /* get quirks */
> + for (idx = 0; idx < ARRAY_SIZE(of_slot_quirks); idx++)
> +

RE: [PATCH] mmc: dwmmc: let device core setup the default pin configuration

2013-03-07 Thread Seungwon Jeon
Hi Thomas,

On Wednesday, March 06, 2013, Thomas Abraham wrote:
> With device core now able to setup the default pin configuration,
> the pin configuration code based on the deprecated Samsung specific
> gpio bindings is removed.

'setup_bus' callback is still useful in dw_mci_drv_data?
Considering the purpose, it would be good to remove.
And, could you change commit prefix for consistency?
dwmmc -> dw_mmc

Thanks,
Seungwon Jeon
> 
> Signed-off-by: Thomas Abraham 
> ---
>  drivers/mmc/host/dw_mmc-exynos.c |   38 
> --
>  1 files changed, 0 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/mmc/host/dw_mmc-exynos.c 
> b/drivers/mmc/host/dw_mmc-exynos.c
> index 72fd0f2..467d043 100644
> --- a/drivers/mmc/host/dw_mmc-exynos.c
> +++ b/drivers/mmc/host/dw_mmc-exynos.c
> @@ -152,43 +152,6 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host)
>   return 0;
>  }
> 
> -static int dw_mci_exynos_setup_bus(struct dw_mci *host,
> - struct device_node *slot_np, u8 bus_width)
> -{
> - int idx, gpio, ret;
> -
> - if (!slot_np)
> - return -EINVAL;
> -
> - /* cmd + clock + bus-width pins */
> - for (idx = 0; idx < NUM_PINS(bus_width); idx++) {
> - gpio = of_get_gpio(slot_np, idx);
> - if (!gpio_is_valid(gpio)) {
> - dev_err(host->dev, "invalid gpio: %d\n", gpio);
> - return -EINVAL;
> - }
> -
> - ret = devm_gpio_request(host->dev, gpio, "dw-mci-bus");
> - if (ret) {
> - dev_err(host->dev, "gpio [%d] request failed\n", gpio);
> - return -EBUSY;
> - }
> - }
> -
> - if (host->pdata->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION)
> - return 0;
> -
> - gpio = of_get_named_gpio(slot_np, "samsung,cd-pinmux-gpio", 0);
> - if (gpio_is_valid(gpio)) {
> - if (devm_gpio_request(host->dev, gpio, "dw-mci-cd"))
> - dev_err(host->dev, "gpio [%d] request failed\n", gpio);
> - } else {
> - dev_info(host->dev, "cd gpio not available");
> - }
> -
> - return 0;
> -}
> -
>  /* Exynos5250 controller specific capabilities */
>  static unsigned long exynos5250_dwmmc_caps[4] = {
>   MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR |
> @@ -205,7 +168,6 @@ static const struct dw_mci_drv_data exynos5250_drv_data = 
> {
>   .prepare_command= dw_mci_exynos_prepare_command,
>   .set_ios= dw_mci_exynos_set_ios,
>   .parse_dt   = dw_mci_exynos_parse_dt,
> - .setup_bus  = dw_mci_exynos_setup_bus,
>  };
> 
>  static const struct of_device_id dw_mci_exynos_match[] = {
> --
> 1.6.6.rc2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


RE: [PATCH v2 1/4] mmc: sdhci-s3c: use the sdhci-pltfm for Samsung-SoC

2012-02-28 Thread Seungwon Jeon
er_data;
>  }
> 
> +static struct sdhci_pltfm_data sdhci_s3c_pdata = {
> + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
> + SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_NO_BUSY_IRQ |
> + SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 |
> + SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC |
> + SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
> + SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_32BIT_DMA_SIZE,
> + .ops= &sdhci_s3c_ops,
> +};
> +
>  static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
>  {
> - struct s3c_sdhci_platdata *pdata;
>   struct sdhci_s3c_drv_data *drv_data;
>   struct device *dev = &pdev->dev;
> + struct sdhci_pltfm_host *pltfm_host;
> + struct sdhci_pltfm_data *pltfm_pdata = &sdhci_s3c_pdata;
>   struct sdhci_host *host;
>   struct sdhci_s3c *sc;
> - struct resource *res;
> - int ret, irq, ptr, clks;
> + int ret, ptr, clks;
> 
>   if (!pdev->dev.platform_data && !pdev->dev.of_node) {
>   dev_err(dev, "no device data specified\n");
>   return -ENOENT;
>   }
> 
> - irq = platform_get_irq(pdev, 0);
> - if (irq < 0) {
> - dev_err(dev, "no irq specified\n");
> - return irq;
> - }
> -
> - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - if (!res) {
> - dev_err(dev, "no memory specified\n");
> - return -ENOENT;
> - }
> -
> - host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c));
> + host = sdhci_pltfm_init(pdev, pltfm_pdata);
>   if (IS_ERR(host)) {
>   dev_err(dev, "sdhci_alloc_host() failed\n");
>   return PTR_ERR(host);
>   }
> - sc = sdhci_priv(host);
> 
> - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> - if (!pdata) {
> + sc = devm_kzalloc(dev, sizeof(struct sdhci_s3c), GFP_KERNEL);
> + if (!sc) {
>   ret = -ENOMEM;
> - goto err_pdata;
> + goto err_alloc_host;
>   }
> 
> + pltfm_host = sdhci_priv(host);
> + pltfm_host->priv = sc;
> +
>   if (pdev->dev.of_node) {
> - ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata);
> + ret = sdhci_s3c_parse_dt(&pdev->dev, host, sc->pdata);
>   if (ret)
> - goto err_pdata;
> + goto err_alloc_host;
>   } else {
> - memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
> + memcpy(&sc->pdata, &pdev->dev.platform_data, sizeof(sc->pdata));
>   sc->ext_cd_gpio = -1; /* invalid gpio number */
>   }
> 
>   drv_data = sdhci_s3c_get_driver_data(pdev);
> + if (drv_data)
> + host->quirks |= drv_data->sdhci_quirks;
> 
> -     sc->host = host;
>   sc->pdev = pdev;
> - sc->pdata = pdata;
> -
> - platform_set_drvdata(pdev, host);
> 
>   sc->clk_io = clk_get(dev, "hsmmc");
>   if (IS_ERR(sc->clk_io)) {
> @@ -602,9 +599,8 @@ static int __devinit sdhci_s3c_probe(struct 
> platform_device *pdev)
> 
>   snprintf(name, 14, "mmc_busclk.%d", ptr);
>   clk = clk_get(dev, name);
> - if (IS_ERR(clk)) {
> + if (IS_ERR(clk))
>   continue;
> - }
> 
>   clks++;
>   sc->clk_bus[ptr] = clk;
> @@ -613,7 +609,10 @@ static int __devinit sdhci_s3c_probe(struct 
> platform_device *pdev)
>* save current clock index to know which clock bus
>* is used later in overriding functions.
>*/
> - sc->cur_clk = ptr;
> + if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
> + pltfm_host->clk = clk;
> + else
We need to keep below?
According to two commits, this seems to be relevant to 
SDHCI_QUIRK_NONSTANDARD_CLOCK.
  mmc: sdhci-s3c: Support controllers with no internal clock 
divider(253e0a7c3dc4b)
  mmc: sdhci-s3c: Remove usage of clk_type member in platform 
data(b77d777eeb0a086)

Thanks,
Seungwon Jeon.

> + sc->cur_clk = ptr;
> 
>   clk_enable(clk);
> 
> @@ -627,63 +626,25 @@ static int __devinit sdhci_s3c_probe(struct 
> platform_device *pdev)
>   goto err_no_busclks;
>   }
> 
> - sc->ioarea = request_mem_region(res->start, resource_size(res),
> - mmc_hostname(host->mmc));
> - if (!sc-&

RE: [PATCH v2 1/4] mmc: sdhci-s3c: use the sdhci-pltfm for Samsung-SoC

2012-03-01 Thread Seungwon Jeon
Jaehoon Chung  wrote:
> On 02/29/2012 03:33 PM, Seungwon Jeon wrote:
> 
> > Hi Jaehoon,
> >
> > Thank you for the patch.
> > Could you check comments below?
> >
> > Jaehoon Chung  wrote:
> >> This patch is change to use the sdhci-pltfm.c
> >>
> >> Signed-off-by: Jaehoon Chung 
> >> Signed-off-by: Kyungmin Park 
> >> ---
> >>  drivers/mmc/host/Kconfig |   20 ++--
> >>  drivers/mmc/host/sdhci-s3c.c |  254 
> >> ++
> >>  2 files changed, 95 insertions(+), 179 deletions(-)
> >>
> >> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> >> index 0c9b3b1..21ea0ba 100644
> >> --- a/drivers/mmc/host/Kconfig
> >> +++ b/drivers/mmc/host/Kconfig
> >> @@ -169,6 +169,8 @@ config MMC_SDHCI_TEGRA
> >>  config MMC_SDHCI_S3C
> >>tristate "SDHCI support on Samsung S3C SoC"
> >>depends on MMC_SDHCI && PLAT_SAMSUNG
> >> +  depends on MMC_SDHCI_PLTFM
> >> +  select MMC_SDHCI_IO_ACCESSORS
> >>help
> >>  This selects the Secure Digital Host Controller Interface (SDHCI)
> >>  often referrered to as the HSMMC block in some of the Samsung S3C
> >> @@ -181,6 +183,14 @@ config MMC_SDHCI_S3C
> >>
> >>  If unsure, say N.
> >>
> >> +config MMC_SDHCI_S3C_DMA
> >> +  bool "DMA support on S3C SDHCI"
> >> +  depends on MMC_SDHCI_S3C && EXPERIMENTAL
> >> +  help
> >> +Enable DMA support on the Samsung S3C SDHCI glue. The DMA
> >> +has proved to be problematic if the controller encounters
> >> +certain errors, and thus should be treated with care.
> >> +
> >>  config MMC_SDHCI_PXAV3
> >>tristate "Marvell MMP2 SD Host Controller support (PXAV3)"
> >>depends on CLKDEV_LOOKUP
> >> @@ -219,16 +229,6 @@ config MMC_SDHCI_SPEAR
> >>
> >>  If unsure, say N.
> >>
> >> -config MMC_SDHCI_S3C_DMA
> >> -  bool "DMA support on S3C SDHCI"
> >> -  depends on MMC_SDHCI_S3C && EXPERIMENTAL
> >> -  help
> >> -Enable DMA support on the Samsung S3C SDHCI glue. The DMA
> >> -has proved to be problematic if the controller encounters
> >> -certain errors, and thus should be treated with care.
> >> -
> >> -YMMV.
> >> -
> >>  config MMC_OMAP
> >>tristate "TI OMAP Multimedia Card Interface support"
> >>depends on ARCH_OMAP
> >> diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
> >> index 3bf509b..0778c38 100644
> >> --- a/drivers/mmc/host/sdhci-s3c.c
> >> +++ b/drivers/mmc/host/sdhci-s3c.c
> >> @@ -28,6 +28,7 @@
> >>  #include 
> >>  #include 
> >>
> >> +#include "sdhci-pltfm.h"
> >>  #include "sdhci.h"
> >>
> >>  #define MAX_BUS_CLK   (4)
> >> @@ -46,9 +47,7 @@
> >>   * @clk_bus: The clocks that are available for the SD/MMC bus clock.
> >>   */
> >>  struct sdhci_s3c {
> >> -  struct sdhci_host   *host;
> >>struct platform_device  *pdev;
> >> -  struct resource *ioarea;
> >>struct s3c_sdhci_platdata *pdata;
> >>unsigned intcur_clk;
> >>int ext_cd_irq;
> >> @@ -71,11 +70,6 @@ struct sdhci_s3c_drv_data {
> >>unsigned intsdhci_quirks;
> >>  };
> >>
> >> -static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
> >> -{
> >> -  return sdhci_priv(host);
> >> -}
> >> -
> >>  /**
> >>   * get_curclk - convert ctrl2 register to clock source number
> >>   * @ctrl2: Control2 register value.
> >> @@ -90,7 +84,8 @@ static u32 get_curclk(u32 ctrl2)
> >>
> >>  static void sdhci_s3c_check_sclk(struct sdhci_host *host)
> >>  {
> >> -  struct sdhci_s3c *ourhost = to_s3c(host);
> >> +  struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> >> +  struct sdhci_s3c *ourhost = pltfm_host->priv;
> >>u32 tmp = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
> >>
> >>if (get_curclk(tmp) != ourhost->cur_clk) {
> >> @@ -110,7 +105,8 @@ static void sdhci_s3c_check_sclk(struct sdhci_host 
> >> *host)
> >>  */
> >>  static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host)
> >>  {
> >

RE: [PATCH v2 1/4] mmc: sdhci-s3c: use the sdhci-pltfm for Samsung-SoC

2012-03-01 Thread Seungwon Jeon
Jaehoon Chung  wrote:
> On 03/02/2012 11:15 AM, Seungwon Jeon wrote:
> 
> > Jaehoon Chung  wrote:
> >> On 02/29/2012 03:33 PM, Seungwon Jeon wrote:
> >>
> >>> Hi Jaehoon,
> >>>
> >>> Thank you for the patch.
> >>> Could you check comments below?
> >>>
> >>> Jaehoon Chung  wrote:
> >>>> This patch is change to use the sdhci-pltfm.c
> >>>>
> >>>> Signed-off-by: Jaehoon Chung 
> >>>> Signed-off-by: Kyungmin Park 
> >>>> ---
> >>>>  drivers/mmc/host/Kconfig |   20 ++--
> >>>>  drivers/mmc/host/sdhci-s3c.c |  254 
> >>>> ++
> >>>>  2 files changed, 95 insertions(+), 179 deletions(-)
> >>>>
> >>>> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> >>>> index 0c9b3b1..21ea0ba 100644
> >>>> --- a/drivers/mmc/host/Kconfig
> >>>> +++ b/drivers/mmc/host/Kconfig
> >>>> @@ -169,6 +169,8 @@ config MMC_SDHCI_TEGRA
> >>>>  config MMC_SDHCI_S3C
> >>>>  tristate "SDHCI support on Samsung S3C SoC"
> >>>>  depends on MMC_SDHCI && PLAT_SAMSUNG
> >>>> +depends on MMC_SDHCI_PLTFM
> >>>> +select MMC_SDHCI_IO_ACCESSORS
> >>>>  help
> >>>>This selects the Secure Digital Host Controller Interface 
> >>>> (SDHCI)
> >>>>often referrered to as the HSMMC block in some of the Samsung 
> >>>> S3C
> >>>> @@ -181,6 +183,14 @@ config MMC_SDHCI_S3C
> >>>>
> >>>>If unsure, say N.
> >>>>
> >>>> +config MMC_SDHCI_S3C_DMA
> >>>> +bool "DMA support on S3C SDHCI"
> >>>> +depends on MMC_SDHCI_S3C && EXPERIMENTAL
> >>>> +help
> >>>> +  Enable DMA support on the Samsung S3C SDHCI glue. The DMA
> >>>> +  has proved to be problematic if the controller encounters
> >>>> +  certain errors, and thus should be treated with care.
> >>>> +
> >>>>  config MMC_SDHCI_PXAV3
> >>>>  tristate "Marvell MMP2 SD Host Controller support (PXAV3)"
> >>>>  depends on CLKDEV_LOOKUP
> >>>> @@ -219,16 +229,6 @@ config MMC_SDHCI_SPEAR
> >>>>
> >>>>If unsure, say N.
> >>>>
> >>>> -config MMC_SDHCI_S3C_DMA
> >>>> -bool "DMA support on S3C SDHCI"
> >>>> -depends on MMC_SDHCI_S3C && EXPERIMENTAL
> >>>> -help
> >>>> -  Enable DMA support on the Samsung S3C SDHCI glue. The DMA
> >>>> -  has proved to be problematic if the controller encounters
> >>>> -  certain errors, and thus should be treated with care.
> >>>> -
> >>>> -  YMMV.
> >>>> -
> >>>>  config MMC_OMAP
> >>>>  tristate "TI OMAP Multimedia Card Interface support"
> >>>>  depends on ARCH_OMAP
> >>>> diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
> >>>> index 3bf509b..0778c38 100644
> >>>> --- a/drivers/mmc/host/sdhci-s3c.c
> >>>> +++ b/drivers/mmc/host/sdhci-s3c.c
> >>>> @@ -28,6 +28,7 @@
> >>>>  #include 
> >>>>  #include 
> >>>>
> >>>> +#include "sdhci-pltfm.h"
> >>>>  #include "sdhci.h"
> >>>>
> >>>>  #define MAX_BUS_CLK (4)
> >>>> @@ -46,9 +47,7 @@
> >>>>   * @clk_bus: The clocks that are available for the SD/MMC bus clock.
> >>>>   */
> >>>>  struct sdhci_s3c {
> >>>> -struct sdhci_host   *host;
> >>>>  struct platform_device  *pdev;
> >>>> -struct resource *ioarea;
> >>>>  struct s3c_sdhci_platdata *pdata;
> >>>>  unsigned intcur_clk;
> >>>>  int ext_cd_irq;
> >>>> @@ -71,11 +70,6 @@ struct sdhci_s3c_drv_data {
> >>>>  unsigned intsdhci_quirks;
> >>>>  };
> >>>>
> >

RE: [PATCH v2 6/6] mmc: dw_mmc: add samsung exynos5250 specific extentions

2012-05-18 Thread Seungwon Jeon
Hi Thomas Abraham,

How about separating the variant for Samsung Exynos.
Like dw_mmc-exynos.c

Thanks,
Seungwon Jeon.

Thomas Abraham wrote:
> The instantiation of the Synopsis Designware controller on Exynos5250
> include extension for SDR and DDR specific tx/rx phase shift timing
> and CIU internal divider. In addition to that, the option to skip the
> command hold stage is also introduced. Add support for these Exynos5250
> specfic extenstions.
> 
> Signed-off-by: Abhilash Kesavan 
> Signed-off-by: Thomas Abraham 
> ---
>  .../devicetree/bindings/mmc/synposis-dw-mshc.txt   |   33 -
>  drivers/mmc/host/dw_mmc-pltfm.c|   15 +++
>  drivers/mmc/host/dw_mmc.c  |   40 
> +++-
>  drivers/mmc/host/dw_mmc.h  |   14 +++
>  include/linux/mmc/dw_mmc.h |6 +++
>  5 files changed, 105 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt
> b/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt
> index 3acd6c9..99b166e 100644
> --- a/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt
> +++ b/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt
> @@ -7,6 +7,8 @@ Required Properties:
> 
>  * compatible: should be one of the following
>   - snps,dw-mshc: for controllers compliant with synopsis dw-mshc.
> + - samsung,exynos5250-dw-mshc: for controllers with Samsung
> +   Exynos5250 specific extentions.
> 
>  * reg: physical base address of the dw-mshc controller and size of its memory
>region.
> @@ -74,13 +76,40 @@ Aliases:
>the following format 'mshc{n}' where n is a unique number for the alias.
> 
> 
> +Samsung Exynos5250 specific properties:
> +
> +* samsung,dw-mshc-sdr-timing: Specifies the value of CUI clock divider, CIU
> +  clock phase shift value in transmit mode and CIU clock phase shift value in
> +  receive mode for single data rate mode operation. Refer notes of the valid
> +  values below.
> +
> +* samsung,dw-mshc-ddr-timing: Specifies the value of CUI clock divider, CIU
> +  clock phase shift value in transmit mode and CIU clock phase shift value in
> +  receive mode for double data rate mode operation. Refer notes of the valid
> +  values below. The order of the cells should be
> +
> +- First Cell:CIU clock divider value.
> +- Second Cell:   CIU clock phase shift value for tx mode.
> +- Third Cell:CIU clock phase shift value for rx mode.
> +
> +  Valid values for SDR and DDR CIU clock timing:
> +
> +- valid values for CIU clock divider, tx phase shift and rx phase shift
> +  is 0 to 7.
> +
> +- When CIU clock divider value is set to 3, all possible 8 phase shift
> +  values can be used.
> +
> +- If CIU clock divider value is 0 (that is divide by 1), both tx and rx
> +  phase shift clocks should be 0.
> +
>  Example:
> 
>The MSHC controller node can be split into two portions, SoC specific and
>board specific portions as listed below.
> 
>   dwmmc0@1220 {
> - compatible = "snps,dw-mshc";
> + compatible = "samsung,exynos5250-dw-mshc";
>   reg = <0x1220 0x1000>;
>   interrupts = <0 75 0>;
>   #address-cells = <1>;
> @@ -94,6 +123,8 @@ Example:
>   no-write-protect;
>   fifo-depth = <0x80>;
>   card-detect-delay = <200>;
> + samsung,dw-mshc-sdr-timing = <2 3 3>;
> + samsung,dw-mshc-ddr-timing = <1 2 3>;
> 
>   slot@0 {
>   reg = <0>;
> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
> index 8d24f6d..900f412 100644
> --- a/drivers/mmc/host/dw_mmc-pltfm.c
> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
> @@ -27,9 +27,24 @@ static struct dw_mci_drv_data synopsis_drv_data = {
>   .ctrl_type  = DW_MCI_TYPE_SYNOPSIS,
>  };
> 
> +static unsigned long exynos5250_dwmmc_caps[4] = {
> + MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR |
> + MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
> + MMC_CAP_CMD23,
> + MMC_CAP_CMD23,
> + MMC_CAP_CMD23,
> +};
> +
> +static struct dw_mci_drv_data exynos5250_drv_data = {
> + .ctrl_type  = DW_MCI_TYPE_EXYNOS5250,
> + .caps   = exynos5250_dwmmc_caps,
> +};
> +
>  static const struct of_device_id dw_mci_pltfm_match[] = {
>   { .compatible = "snps,dw-mshc",
>   .data = (void *)&synopsis_drv_data, },
> + { .compatible = "samsung,exynos5250-dw-mshc",
>

RE: [PATCH v3 6/6] mmc: dw_mmc: add samsung exynos5250 specific extentions

2012-07-18 Thread Seungwon Jeon
erty not found, using "
>   "value of FIFOTH register as default\n");
> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
> index 1ecaa02..6c17282 100644
> --- a/drivers/mmc/host/dw_mmc.h
> +++ b/drivers/mmc/host/dw_mmc.h
> @@ -53,6 +53,7 @@
>  #define SDMMC_IDINTEN0x090
>  #define SDMMC_DSCADDR0x094
>  #define SDMMC_BUFADDR0x098
> +#define SDMMC_CLKSEL 0x09C /* specific to Samsung Exynos5250 */
>  #define SDMMC_DATA(x)(x)
> 
>  /*
> @@ -111,6 +112,7 @@
>  #define SDMMC_INT_ERROR  0xbfc2
>  /* Command register defines */
>  #define SDMMC_CMD_START  BIT(31)
> +#define SDMMC_CMD_USE_HOLD_REG   BIT(29)
>  #define SDMMC_CMD_CCS_EXPBIT(23)
>  #define SDMMC_CMD_CEATA_RD   BIT(22)
>  #define SDMMC_CMD_UPD_CLKBIT(21)
> @@ -142,6 +144,17 @@
>  /* Version ID register define */
>  #define SDMMC_GET_VERID(x)   ((x) & 0x)
> 
> +#define DW_MCI_DEF_SDR_TIMING0x03030002
> +#define DW_MCI_DEF_DDR_TIMING0x03020001
What is the basis for these timing?
These values is board-specific.

> +#define SDMMC_CLKSEL_CCLK_SAMPLE(x)  (((x) & 3) << 0)
> +#define SDMMC_CLKSEL_CCLK_DRIVE(x)   (((x) & 3) << 16)
> +#define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 3) << 24)
If it's for exynos5, it will be 7 not 3.

> +#define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) |  \
> + SDMMC_CLKSEL_CCLK_DRIVE(y) |\
> + SDMMC_CLKSEL_CCLK_DIVIDER(z))
> +#define SDMMC_CLKSEL_GET_DIVRATIO(x) x) >> 24) & 0x7) + 1)
> +#define SDMMC_CLKSEL_GET_SELCLK_DRV(x)   (((x) >> 16) & 0x7)
> +
Is this patch considered only for exynos5250?
In case of exynos4210, the number of bits is different.
If upper macros is backward-compatible, it would be better.

Best regards,
Seungwon Jeon

>  /* Register access macros */
>  #define mci_readl(dev, reg)  \
>   __raw_readl((dev)->regs + SDMMC_##reg)
> @@ -184,6 +197,7 @@ extern int dw_mci_resume(struct dw_mci *host);
> 
>  /* Variations in the dw_mci controller */
>  #define DW_MCI_TYPE_SYNOPSIS 0
> +#define DW_MCI_TYPE_EXYNOS5250   1 /* Samsung Exynos5250 
> Extensions */
> 
>  /* dw_mci platform driver data */
>  struct dw_mci_drv_data {
> diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
> index ae45e4f..32c778f 100644
> --- a/include/linux/mmc/dw_mmc.h
> +++ b/include/linux/mmc/dw_mmc.h
> @@ -82,6 +82,8 @@ struct mmc_data;
>   * @biu_clk: Pointer to bus interface unit clock instance.
>   * @ciu_clk: Pointer to card interface unit clock instance.
>   * @slot: Slots sharing this MMC controller.
> + * @sdr_timing: Clock phase shifting for driving and sampling in sdr mode
> + * @ddr_timing: Clock phase shifting for driving and sampling in ddr mode
>   * @fifo_depth: depth of FIFO.
>   * @data_shift: log2 of FIFO item size.
>   * @part_buf_start: Start index in part_buf.
> @@ -166,6 +168,10 @@ struct dw_mci {
>   struct clk  *ciu_clk;
>   struct dw_mci_slot  *slot[MAX_MCI_SLOTS];
> 
> + /* Phase Shift Value (for exynos5250 variant) */
> + u32 sdr_timing;
> + u32 ddr_timing;
> +
>   /* FIFO push and pull */
>   int fifo_depth;
>   int data_shift;
> --
> 1.6.6.rc2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


RE: [PATCH 3/9] mmc: dw_mmc: lookup for optional biu and ciu clocks

2012-07-19 Thread Seungwon Jeon
July 17, 2012, Thomas Abraham  wrote:
> Some platforms allow for clock gating and control of bus interface unit clock
> and card interface unit clock. Add support for clock lookup of optional biu
> and ciu clocks for clock gating and clock speed determination.
> 
> Signed-off-by: Abhilash Kesavan 
> Signed-off-by: Thomas Abraham 
> ---
>  drivers/mmc/host/dw_mmc.c  |   39 ---
>  include/linux/mmc/dw_mmc.h |4 
>  2 files changed, 40 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index cd58063..ebd22d8 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -1953,13 +1953,30 @@ int dw_mci_probe(struct dw_mci *host)
>   return -ENODEV;
>   }
> 
> - if (!host->pdata->bus_hz) {
> + host->biu_clk = clk_get(host->dev, "biu");
> + if (IS_ERR(host->biu_clk))
> + dev_dbg(host->dev, "biu clock not available\n");
> + else
> + clk_prepare_enable(host->biu_clk);
> +
> + host->ciu_clk = clk_get(host->dev, "ciu");
> + if (IS_ERR(host->ciu_clk))
> + dev_dbg(host->dev, "ciu clock not available\n");
> + else
> + clk_prepare_enable(host->ciu_clk);
> +
> + if (IS_ERR(host->ciu_clk))
> + host->bus_hz = host->pdata->bus_hz;
> + else
> + host->bus_hz = clk_get_rate(host->ciu_clk);
I have posted similar patch some time back.
bus_hz represents input rate for cclk_in of mshc.
Host of samsung soc doesn't use input clock from system directly.
As you have introduced CLKSEL in your another patch, input clock can be changed 
prior to cclk_in.
For non-samsung  host, we don't need to consider this with generic way?

Thanks,
Seungwon Jeon

> +
> + if (!host->bus_hz) {
>   dev_err(host->dev,
>   "Platform data must supply bus speed\n");
> - return -ENODEV;
> + ret = -ENODEV;
> + goto err_clk;
>   }
> 
> - host->bus_hz = host->pdata->bus_hz;
>   host->quirks = host->pdata->quirks;
> 
>   spin_lock_init(&host->lock);
> @@ -2109,6 +2126,16 @@ err_dmaunmap:
>   regulator_disable(host->vmmc);
>   regulator_put(host->vmmc);
>   }
> +
> +err_clk:
> + if (!IS_ERR(host->ciu_clk)) {
> + clk_disable_unprepare(host->ciu_clk);
> + clk_put(host->ciu_clk);
> + }
> + if (!IS_ERR(host->biu_clk)) {
> + clk_disable_unprepare(host->biu_clk);
> + clk_put(host->biu_clk);
> + }
>   return ret;
>  }
>  EXPORT_SYMBOL(dw_mci_probe);
> @@ -2142,6 +2169,12 @@ void dw_mci_remove(struct dw_mci *host)
>   regulator_put(host->vmmc);
>   }
> 
> + if (!IS_ERR(host->ciu_clk))
> + clk_disable_unprepare(host->ciu_clk);
> + if (!IS_ERR(host->biu_clk))
> + clk_disable_unprepare(host->biu_clk);
> + clk_put(host->ciu_clk);
> + clk_put(host->biu_clk);
>  }
>  EXPORT_SYMBOL(dw_mci_remove);
> 
> diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
> index a37a573..787ad56 100644
> --- a/include/linux/mmc/dw_mmc.h
> +++ b/include/linux/mmc/dw_mmc.h
> @@ -78,6 +78,8 @@ struct mmc_data;
>   * @data_offset: Set the offset of DATA register according to VERID.
>   * @dev: Device associated with the MMC controller.
>   * @pdata: Platform data associated with the MMC controller.
> + * @biu_clk: Pointer to bus interface unit clock instance.
> + * @ciu_clk: Pointer to card interface unit clock instance.
>   * @slot: Slots sharing this MMC controller.
>   * @fifo_depth: depth of FIFO.
>   * @data_shift: log2 of FIFO item size.
> @@ -158,6 +160,8 @@ struct dw_mci {
>   u16 data_offset;
>   struct device   *dev;
>   struct dw_mci_board *pdata;
> + struct clk  *biu_clk;
> + struct clk  *ciu_clk;
>   struct dw_mci_slot  *slot[MAX_MCI_SLOTS];
> 
>   /* FIFO push and pull */
> --
> 1.6.6.rc2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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


RE: [PATCH v3 6/6] mmc: dw_mmc: add samsung exynos5250 specific extentions

2012-07-20 Thread Seungwon Jeon
July 20, 2012, Thomas Abraham  wrote:
> On 19 July 2012 09:21, Seungwon Jeon  wrote:
> > Hi,
> >
> > This version does not seems to consider previous reviews fully.
> > Could you check the comments below?
> 
> I did try to address all the comments. I will check again and resubmit
> if I have missed anything.
> 
> >
> > July 12, 2012, Thomas Abraham  wrote:
> >> The instantiation of the Synopsis Designware controller on Exynos5250
> >> include extension for SDR and DDR specific tx/rx phase shift timing
> >> and CIU internal divider. In addition to that, the option to skip the
> >> command hold stage is also introduced. Add support for these Exynos5250
> >> specfic extenstions.
> >>
> >> Signed-off-by: Abhilash Kesavan 
> >> Signed-off-by: Thomas Abraham 
> >> ---
> >>  .../devicetree/bindings/mmc/synposis-dw-mshc.txt   |   38 
> >> ++-
> >>  drivers/mmc/host/dw_mmc-pltfm.c|   15 +++
> >>  drivers/mmc/host/dw_mmc.c  |   40 
> >> +++-
> >>  drivers/mmc/host/dw_mmc.h  |   14 +++
> >>  include/linux/mmc/dw_mmc.h |6 +++
> >>  5 files changed, 110 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt
> >> b/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt
> >> index 3acd6c9..69d78c1 100644
> >> --- a/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt
> >> +++ b/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt
> >> @@ -7,6 +7,8 @@ Required Properties:
> >>
> >>  * compatible: should be one of the following
> >>   - snps,dw-mshc: for controllers compliant with synopsis dw-mshc.
> >> + - samsung,exynos5250-dw-mshc: for controllers with Samsung
> >> +   Exynos5250 specific extentions.
> >>
> >>  * reg: physical base address of the dw-mshc controller and size of its 
> >> memory
> >>region.
> >> @@ -74,13 +76,45 @@ Aliases:
> >>the following format 'mshc{n}' where n is a unique number for the alias.
> >>
> >>
> >> +Samsung Exynos4/5 specific properties:
> >> +
> >> +Some of the variants of Exynos4 (such as Exynos4412) and Exynos5 SoC's
> >> +includes few extensions to the Synopsis Designware Mobile Storage Host
> >> +Controller. The following properties are used to describe those 
> >> extensions.
> >> +
> >> +* samsung,dw-mshc-sdr-timing: Specifies the value of CUI clock divider, 
> >> CIU
> >> +  clock phase shift value in transmit mode and CIU clock phase shift 
> >> value in
> >> +  receive mode for single data rate mode operation. Refer notes of the 
> >> valid
> >> +  values below.
> >> +
> >> +* samsung,dw-mshc-ddr-timing: Specifies the value of CUI clock divider, 
> >> CIU
> >> +  clock phase shift value in transmit mode and CIU clock phase shift 
> >> value in
> >> +  receive mode for double data rate mode operation. Refer notes of the 
> >> valid
> >> +  values below. The order of the cells should be
> >> +
> >> +- First Cell:CIU clock divider value (applicable only for Exynos5
> >> + SoC's, should be zero for Exynos4 SoC's)
> >> +- Second Cell:   CIU clock phase shift value for tx mode.
> >> +- Third Cell:CIU clock phase shift value for rx mode.
> >> +
> >> +  Valid values for SDR and DDR CIU clock timing for Exynos5250:
> >> +
> >> +- valid values for CIU clock divider, tx phase shift and rx phase 
> >> shift
> >> +  is 0 to 7.
> >> +
> >> +- When CIU clock divider value is set to 3, all possible 8 phase shift
> >> +  values can be used.
> >> +
> >> +- If CIU clock divider value is 0 (that is divide by 1), both tx and 
> >> rx
> >> +  phase shift clocks should be 0.
> >> +
> >>  Example:
> >>
> >>The MSHC controller node can be split into two portions, SoC specific 
> >> and
> >>board specific portions as listed below.
> >>
> >>   dwmmc0@1220 {
> >> - compatible = "snps,dw-mshc";
> >> + compatible = "samsung,exynos5250-dw-mshc";
> >>   reg = <0x122000

RE: [PATCH v3 6/6] mmc: dw_mmc: add samsung exynos5250 specific extentions

2012-07-23 Thread Seungwon Jeon
July 23, 2012, Thomas Abraham  wrote:
> On 20 July 2012 16:08, Seungwon Jeon  wrote:
> > July 20, 2012, Thomas Abraham  wrote:
> >> On 19 July 2012 09:21, Seungwon Jeon  wrote:
> 
> [...]
> 
> >> >> +static unsigned long exynos5250_dwmmc_caps[4] = {
> >> >> + MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR |
> >> >> + MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
> >> >> + MMC_CAP_CMD23,
> >> >> + MMC_CAP_CMD23,
> >> >> + MMC_CAP_CMD23,
> >> >> +};
> >> >> +
> >> > Kyungmin Park has already pointed .
> >> > It's not still proper place for board specific caps.
> >> > If I'm incorrect, please let me know.
> >> > And why MMC_CAP_CMD23 is default caps for all channel of hosts?
> >>
> >> The cap listed above are specifying controller capabilities for dw-mmc
> >> controllers on Exynos5 SoC. They are not board specific caps. All the
> >> Exynos5 dw-mmc controllers can support MMC_CAP_CMD23 cap and hence, it
> >> has been listed for all the controllers. Please let me know if you
> >> feel there is any change required here.
> > MMC_CAP_8_BIT_DATA could be dependent on board.
> 
> A controller can have the MMC_CAP_8_BIT_DATA capability but the board
> will decide the bus-width. The bus-width is specified in the dts files
> of each board (or platform data). The bus-width for data transfer is
> then decided by the MMC core code based on the caps and the bus-width
> information. So MMC_CAP_8_BIT_DATA can be specified irrespective   of
> whether the board supports 8-bit or not.
> 
> > I agree about MMC_CAP_CMD23.
> > Additionally, MMC_CAP_CMD23 is applied for dw-mmc host driver without 
> > regard to Exynos5.
> 
> The caps listed in exynos5250_dwmmc_caps is applicable only for
> Exynos5 SoC's. Could you please let me know if there is anything
> incorrect here.
I mean that MMC_CAP_CMD23 is a capability which is implemented in driver 
without dependency of SOC.
So, other soc also includes MMC_CAP_CMD23.
It'd rather make a default caps than list in specific soc, considering the 
other soc.

> 
> [...]
> 
> >> >> + if (slot->host->drv_data->ctrl_type == DW_MCI_TYPE_EXYNOS5250) {
> >> >> + slot->host->bus_hz = clk_get_rate(slot->host->ciu_clk);
> >> >> + slot->host->bus_hz /= SDMMC_CLKSEL_GET_DIVRATIO(
> >> >> + mci_readl(slot->host, CLKSEL));
> >> >> + }
> >> > As you know, CLKSEL is specific for Samsung soc.
> >> > 0x09C(CLKSEL)  is reserved area in Synopsys memory map.
> >> > In case of non-samsung-soc, we cannot ensure this usage.
> >> > In previous version, I have suggested separating the variant into 
> >> > another file.
> >>
> >> There is a check for type of SoC before using 0x9C as CLKSEL register.
> > Do you mean checking DW_MCI_TYPE_EXYNOS5250?
> > But Above two case(ddr_timing/sdr_timing), CLKSEL can be accessed on other 
> > soc's.
> 
> The tests have only been completed on Exynos5250. I do not have boards
> for other Samsung SoC's which have a dw_mmc port connected and used on
> the board. When we have other platforms tested with this patchset, we
> can extend the 'if' check in the above code for other SoC's.
My meaning  seem to be passed incorrectly.

+   if (ios->timing == MMC_TIMING_UHS_DDR50) {
regs |= (0x1 << slot->id) << 16;
-   else
+   mci_writel(slot->host, CLKSEL, slot->host->ddr_timing);
What is the execution for non-samsung soc?
CLKSEL register is valid  only for Exynos.
dw_mci_set_ios shoud be aware of this.

+   } else {
regs &= ~(0x1 << slot->id) << 16;
+   mci_writel(slot->host, CLKSEL, slot->host->sdr_timing);
This line is same.
+   }
+

> 
> >
> >> Other implementations of dw-mmc might define custom register at 0x9C
> > Even so, register field can be different with Samsung soc.
> 
> Yes, with the correct checks for the type of SoC, differences in the
> usage of 0x9C register can be handled.
> 
> >
> >> but this will code will not execute on other SoC's and will not break
> >> anything on other implementations. Regarding spliting this Exynos
> >> specific code into another file, I prefer not to do it for now.
> >> Spliting the code means adding new definitions of callback functions
> >> which I am not sure is really required. The present

RE: [PATCH V2] mmc: dwmmc: Add quirk for broken Hardware Config

2012-07-23 Thread Seungwon Jeon
Hi Girish,

July 23, 2012, Girish K S  wrote:
> In some Soc'S that integrate Designware mmc host controllers, the
> HCON register is broken. The hardware configuration is not
> updated. One specific usecase is the IDMAC. In Exysons5 SoC
> there exist a internal DMA, but the HCON register's DMA_INTERFACE
> field is not set to indicate its existance.
> 
> This quirk can be used in such case to force the existance broken
> HCON field.
> 
> changes in v2:
>   -moved the implementation to quirk framework as per venkat's
>review comment.
> changes in v1:
>   -modified the caps2 field access per controller index.Reported
>by Jaehoon Chung .
>   -replaced the pointer to device with the pointer to platform
>device in struct dw_mci.
Change related to adding pointer of platform_device is needed in this patch 
seriously?
I guess that the purpose is to get id of platform_device in case of non-dt.
Although a lot of replace is done throughout dw_mmc, actual usage is only in 
dw_get_platform_device_id.
You can split it into another patch if this change is needed, or it's good to 
use other way.
For example, to_platform_device macro is useful to get pointer of 
platform_device.

Best regards,
Seungwon Jeon

>   -updated driver data for all 4 mmc controllers of exynos5 SoC.
>   -added non device-tree support for ctrl_id access.
> 
> Signed-off-by: Girish K S 
> ---
>  drivers/mmc/host/dw_mmc-pltfm.c |   10 +++-
>  drivers/mmc/host/dw_mmc.c   |  151 
> ---
>  drivers/mmc/host/dw_mmc.h   |1 +
>  include/linux/mmc/dw_mmc.h  |4 +-
>  4 files changed, 107 insertions(+), 59 deletions(-)
> 
> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
> index 900f412..7d31e90 100644
> --- a/drivers/mmc/host/dw_mmc-pltfm.c
> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
> @@ -35,9 +35,17 @@ static unsigned long exynos5250_dwmmc_caps[4] = {
>   MMC_CAP_CMD23,
>  };
> 
> +static unsigned long exynos5250_dwmmc_quirks[4] = {
> + DW_MCI_QUIRK_NO_HCON_DMA_INFO,
> + DW_MCI_QUIRK_NO_HCON_DMA_INFO,
> + DW_MCI_QUIRK_NO_HCON_DMA_INFO,
> + DW_MCI_QUIRK_NO_HCON_DMA_INFO,
> +};
> +
>  static struct dw_mci_drv_data exynos5250_drv_data = {
>   .ctrl_type  = DW_MCI_TYPE_EXYNOS5250,
>   .caps   = exynos5250_dwmmc_caps,
> + .quirks = exynos5250_dwmmc_quirks,
>  };
> 
>  static const struct of_device_id dw_mci_pltfm_match[] = {
> @@ -74,7 +82,7 @@ static int dw_mci_pltfm_probe(struct platform_device *pdev)
>   goto err_free;
>   }
> 
> - host->dev = &pdev->dev;
> + host->pdev = pdev;
>   host->irq_flags = 0;
>   host->pdata = pdev->dev.platform_data;
>   ret = -ENOMEM;
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 000da16..b32e200 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -283,8 +283,10 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, 
> struct mmc_command *cmd)
>  static void dw_mci_start_command(struct dw_mci *host,
>struct mmc_command *cmd, u32 cmd_flags)
>  {
> + struct device *dev = &host->pdev->dev;
> +
>   host->cmd = cmd;
> - dev_vdbg(host->dev,
> + dev_vdbg(dev,
>"start command: ARGR=0x%08x CMDR=0x%08x\n",
>cmd->arg, cmd_flags);
> 
> @@ -323,10 +325,11 @@ static int dw_mci_get_dma_dir(struct mmc_data *data)
>  static void dw_mci_dma_cleanup(struct dw_mci *host)
>  {
>   struct mmc_data *data = host->data;
> + struct device *dev = &host->pdev->dev;
> 
>   if (data)
>   if (!data->host_cookie)
> - dma_unmap_sg(host->dev,
> + dma_unmap_sg(dev,
>data->sg,
>data->sg_len,
>dw_mci_get_dma_dir(data));
> @@ -351,8 +354,9 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host)
>  static void dw_mci_idmac_complete_dma(struct dw_mci *host)
>  {
>   struct mmc_data *data = host->data;
> + struct device *dev = &host->pdev->dev;
> 
> - dev_vdbg(host->dev, "DMA complete\n");
> + dev_vdbg(dev, "DMA complete\n");
> 
>   host->dma_ops->cleanup(host);
> 
> @@ -420,10 +424,27 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, 
> unsigned int sg_len)
>   mci_writel(host, PLDMND, 1);
>  }
> 
> +static int dw_get_platform_device_id(struct dw_mci *host)
> +{
&

RE: [PATCH v4 9/9] mmc: dw_mmc: add support for exynos specific implementation of dw-mshc

2012-08-28 Thread Seungwon Jeon
em alloc failed for private data\n");
> + return -ENOMEM;
> + }
> +
> + for (idx = 0; idx < ARRAY_SIZE(exynos_compat); idx++) {
> + if (of_device_is_compatible(host->dev->of_node,
> + exynos_compat[idx].compatible))
> + priv->ctrl_type = exynos_compat[idx].ctrl_type;
> + }
> +
> + host->priv = priv;
> + return 0;
> +}
> +
> +static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
> +{
> + struct dw_mci_exynos_priv_data *priv = host->priv;
> + u8 drv;
> +
> + /*
> +  * Exynos4412 and Exynos5250 extends the use of CMD register with the
> +  * use of bit 29 (which is reserved on standard MSHC controllers) for
> +  * optionally bypassing the HOLD register for command and data. The
> +  * HOLD register should be bypassed in case there is no phase shift
> +  * applied on CMD/DATA that is sent to the card.
> +  */
> + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412)
> + drv = SDMMC_CLKSEL_GET_DRV_WD2(mci_readl(host, CLKSEL));
As it  has been mentioned previously,  only exynos4210 uses 2-bit.
So SDMMC_CLKSEL_GET_DRV_WD3 will be right in exynos4412.

> + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5250)
> + drv = SDMMC_CLKSEL_GET_DRV_WD3(mci_readl(host, CLKSEL));
> + else
> + return;
> + if (drv)
> + *cmdr |= SDMMC_CMD_USE_HOLD_REG;
> +}
> +
> +static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
> +{
> + struct dw_mci_exynos_priv_data *priv = host->priv;
> +
> + if (ios->timing == MMC_TIMING_UHS_DDR50)
> + mci_writel(host, CLKSEL, priv->ddr_timing);
> + else
> + mci_writel(host, CLKSEL, priv->sdr_timing);
> +
> + host->bus_hz = clk_get_rate(host->ciu_clk);
> + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5250)
> + host->bus_hz /= SDMMC_CLKSEL_GET_DIVRATIO(
> +     mci_readl(host, CLKSEL));
bus_hz should be recalculated for exynoxs4 as well.
Could you check the previous mailing?

> +}
> +
> +static int dw_mci_exynos_parse_dt(struct dw_mci *host)
> +{
> + struct dw_mci_exynos_priv_data *priv = host->priv;
> + u32 timing[3];
> +
> + if (of_property_read_u32_array(host->dev->of_node,
> + "samsung,dw-mshc-sdr-timing", timing, 3))
> + priv->sdr_timing = DW_MCI_DEF_SDR_TIMING;
> + else
> + priv->sdr_timing = SDMMC_CLKSEL_TIMING(timing[0],
> + timing[1], timing[2]);
> +
> + if (of_property_read_u32_array(host->dev->of_node,
> + "samsung,dw-mshc-ddr-timing", timing, 3))
> + priv->ddr_timing = DW_MCI_DEF_DDR_TIMING;
> + else
> + priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0],
> + timing[1], timing[2]);
> + return 0;
DW_MCI_DEF_SDR_TIMING and DW_MCI_DEF_DDR_TIMING are board-specific timing 
values.
So, these values can't be used commonly. It has been already discussed.
If this property is empty, returning error with message will be fine.
Currently just 0 is always returned.

Thanks,
Seungwon Jeon

> +}
> +
> +static int dw_mci_exynos_setup_bus(struct dw_mci *host,
> + struct device_node *slot_np, u8 bus_width)
> +{
> + int idx, gpio, ret;
> +
> + if (!slot_np)
> + return -EINVAL;
> +
> + /* cmd + clock + bus-width pins */
> + for (idx = 0; idx < NUM_PINS(bus_width); idx++) {
> + gpio = of_get_gpio(slot_np, idx);
> + if (!gpio_is_valid(gpio)) {
> + dev_err(host->dev, "invalid gpio: %d\n", gpio);
> + return -EINVAL;
> + }
> +
> + ret = devm_gpio_request(host->dev, gpio, "dw-mci-bus");
> + if (ret) {
> + dev_err(host->dev, "gpio [%d] request failed\n", gpio);
> + return -EBUSY;
> + }
> + }
> +
> + gpio = of_get_named_gpio(slot_np, "wp-gpios", 0);
> + if (gpio_is_valid(gpio)) {
> + if (devm_gpio_request(host->dev, gpio, "dw-mci-wp"))
> + dev_info(host->dev, "gpio [%d] request failed\n",
> + gpio);
> + } else {
> + dev_info(host->dev, "wp gpio not available");
> + host->pdata->quirks |= DW_MCI_QUIRK_NO_WRITE_PRO

RE: [PATCH v4 4/9] mmc: dw_mmc: lookup for optional biu and ciu clocks

2012-08-28 Thread Seungwon Jeon
On Sunday, August 26, 2012 Thomas Abraham  wrote:
> Some platforms allow for clock gating and control of bus interface unit clock
> and card interface unit clock. Add support for clock lookup of optional biu
> and ciu clocks for clock gating and clock speed determination.
> 
> Signed-off-by: Abhilash Kesavan 
> Signed-off-by: Thomas Abraham 
> ---
>  drivers/mmc/host/dw_mmc.c  |   42 +++---
>  include/linux/mmc/dw_mmc.h |4 
>  2 files changed, 43 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index cd58063..679473c 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -1953,18 +1953,38 @@ int dw_mci_probe(struct dw_mci *host)
>   return -ENODEV;
>   }
> 
> - if (!host->pdata->bus_hz) {
> + host->biu_clk = clk_get(host->dev, "biu");
> + if (IS_ERR(host->biu_clk))
> + dev_dbg(host->dev, "biu clock not available\n");
> + else
> + clk_prepare_enable(host->biu_clk);
> +
> + host->ciu_clk = clk_get(host->dev, "ciu");
> + if (IS_ERR(host->ciu_clk))
> + dev_dbg(host->dev, "ciu clock not available\n");
> + else
> + clk_prepare_enable(host->ciu_clk);
> +
> + if (IS_ERR(host->ciu_clk))
> + host->bus_hz = host->pdata->bus_hz;
> + else
> + host->bus_hz = clk_get_rate(host->ciu_clk);
I have remained comment in [PATCH 3/9] mmc: dw_mmc: lookup for optional biu and 
ciu clocks
Could I get your opinion?

Thanks,
Seungwon Jeon

> +
> + if (!host->bus_hz) {
>   dev_err(host->dev,
>   "Platform data must supply bus speed\n");
> - return -ENODEV;
> + ret = -ENODEV;
> + goto err_clk;
>   }
> 
> - host->bus_hz = host->pdata->bus_hz;
>   host->quirks = host->pdata->quirks;
> 
>   spin_lock_init(&host->lock);
>   INIT_LIST_HEAD(&host->queue);
> 
> + host->dma_ops = host->pdata->dma_ops;
> + dw_mci_init_dma(host);
> +
>   /*
>* Get the host data width - this assumes that HCON has been set with
>* the correct values.
> @@ -2109,6 +2129,16 @@ err_dmaunmap:
>   regulator_disable(host->vmmc);
>   regulator_put(host->vmmc);
>   }
> +
> +err_clk:
> + if (!IS_ERR(host->ciu_clk)) {
> + clk_disable_unprepare(host->ciu_clk);
> + clk_put(host->ciu_clk);
> + }
> + if (!IS_ERR(host->biu_clk)) {
> + clk_disable_unprepare(host->biu_clk);
> + clk_put(host->biu_clk);
> + }
>   return ret;
>  }
>  EXPORT_SYMBOL(dw_mci_probe);
> @@ -2142,6 +2172,12 @@ void dw_mci_remove(struct dw_mci *host)
>   regulator_put(host->vmmc);
>   }
> 
> + if (!IS_ERR(host->ciu_clk))
> + clk_disable_unprepare(host->ciu_clk);
> + if (!IS_ERR(host->biu_clk))
> + clk_disable_unprepare(host->biu_clk);
> + clk_put(host->ciu_clk);
> + clk_put(host->biu_clk);
>  }
>  EXPORT_SYMBOL(dw_mci_remove);
> 
> diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
> index a37a573..787ad56 100644
> --- a/include/linux/mmc/dw_mmc.h
> +++ b/include/linux/mmc/dw_mmc.h
> @@ -78,6 +78,8 @@ struct mmc_data;
>   * @data_offset: Set the offset of DATA register according to VERID.
>   * @dev: Device associated with the MMC controller.
>   * @pdata: Platform data associated with the MMC controller.
> + * @biu_clk: Pointer to bus interface unit clock instance.
> + * @ciu_clk: Pointer to card interface unit clock instance.
>   * @slot: Slots sharing this MMC controller.
>   * @fifo_depth: depth of FIFO.
>   * @data_shift: log2 of FIFO item size.
> @@ -158,6 +160,8 @@ struct dw_mci {
>   u16 data_offset;
>   struct device   *dev;
>   struct dw_mci_board *pdata;
> + struct clk  *biu_clk;
> + struct clk  *ciu_clk;
>   struct dw_mci_slot  *slot[MAX_MCI_SLOTS];
> 
>   /* FIFO push and pull */
> --
> 1.6.6.rc2

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


RE: [PATCH v4 9/9] mmc: dw_mmc: add support for exynos specific implementation of dw-mshc

2012-08-28 Thread Seungwon Jeon
On Tuesday, August 28, 2012 Thomas Abraham  wrote:
> Hi Seungwon,
> 
> On 28 August 2012 12:36, Seungwon Jeon  wrote:
> > Hi Thomas,
> >
> > Thank you for your effort.
> > Some reviews seems like to be omitted. Please check more.
> >
> > On Sunday, August 26, 2012 Thomas Abraham  wrote:
> >> Samsung Exynos SoC's extend the dw-mshc controller for additional clock 
> >> and bus
> >> control. Add support for these extensions and include provide device tree 
> >> based
> >> discovery suppory as well.
> 
> [...]
> 
> >> +static struct dw_mci_exynos_compatible {
> >> + char*compatible;
> >> + enum dw_mci_exynos_type ctrl_type;
> >> +} exynos_compat[] = {
> >> + {
> >> + .compatible = "samsung,exynos4210-dw-mshc",
> >> + .ctrl_type  = DW_MCI_TYPE_EXYNOS4210,
> >> + }, {
> >> + .compatible = "samsung,exynos4210-dw-mshc",
> > typo? exynos4412-dw-mshc is expected.
> 
> Yes, that was a typo. I will fix it.
> 
> [...]
> 
> >> +static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
> >> +{
> >> + struct dw_mci_exynos_priv_data *priv = host->priv;
> >> + u8 drv;
> >> +
> >> + /*
> >> +  * Exynos4412 and Exynos5250 extends the use of CMD register with the
> >> +  * use of bit 29 (which is reserved on standard MSHC controllers) for
> >> +  * optionally bypassing the HOLD register for command and data. The
> >> +  * HOLD register should be bypassed in case there is no phase shift
> >> +  * applied on CMD/DATA that is sent to the card.
> >> +  */
> >> + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412)
> >> + drv = SDMMC_CLKSEL_GET_DRV_WD2(mci_readl(host, CLKSEL));
> > As it  has been mentioned previously,  only exynos4210 uses 2-bit.
> > So SDMMC_CLKSEL_GET_DRV_WD3 will be right in exynos4412.
> 
> In the Exynos4412 user manual that I referred, the SelClk_Drv and
> SelClk_Sample bit fields of the CLKSEL register are 2 bits wide. Could
> you please confirm that these two bit-fields are in fact 3 bits wide?
I think you are referring old manual. 3-bit is right.
I hope you find this.

> 
> >
> >> + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5250)
> >> + drv = SDMMC_CLKSEL_GET_DRV_WD3(mci_readl(host, CLKSEL));
> >> + else
> >> + return;
> >> + if (drv)
> >> + *cmdr |= SDMMC_CMD_USE_HOLD_REG;
> >> +}
> >> +
> >> +static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios 
> >> *ios)
> >> +{
> >> + struct dw_mci_exynos_priv_data *priv = host->priv;
> >> +
> >> + if (ios->timing == MMC_TIMING_UHS_DDR50)
> >> + mci_writel(host, CLKSEL, priv->ddr_timing);
> >> + else
> >> + mci_writel(host, CLKSEL, priv->sdr_timing);
> >> +
> >> + host->bus_hz = clk_get_rate(host->ciu_clk);
> >> + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5250)
> >> + host->bus_hz /= SDMMC_CLKSEL_GET_DIVRATIO(
> >> + mci_readl(host, CLKSEL));
> > bus_hz should be recalculated for exynoxs4 as well.
> > Could you check the previous mailing?
> 
> Exynos4 does not have the additional clock divisor, as in Exynos5250.
> Could you please explain why the bus_hz clock should be divided in
> Exynos4?
Yes, clock divisor is used in Exynos5250.
In case of Exynos4 SoC's, divider value(DIVRATIO) isn't exposed to register.
But  SDCLKIN is divided by fixed divider value internally.
As mentioned previously, divider is used like below.
Exynos4210 : 2
Exynos4X12 : 4

> 
> >
> >> +}
> >> +
> >> +static int dw_mci_exynos_parse_dt(struct dw_mci *host)
> >> +{
> >> + struct dw_mci_exynos_priv_data *priv = host->priv;
> >> + u32 timing[3];
> >> +
> >> + if (of_property_read_u32_array(host->dev->of_node,
> >> + "samsung,dw-mshc-sdr-timing", timing, 3))
> >> + priv->sdr_timing = DW_MCI_DEF_SDR_TIMING;
> >> + else
> >> + priv->sdr_timing = SDMMC_CLKSEL_TIMING(timing[0],
> >> + timing[1], timing[2]);
> >> +
> >> + if (of_property_read_u32_array(host->dev->of_node,
> 

RE: [PATCH v5 9/9] mmc: dw_mmc: add support for exynos specific implementation of dw-mshc

2012-09-05 Thread Seungwon Jeon
w_mci *host)
> +{
> + struct dw_mci_exynos_priv_data *priv;
> + int idx;
> +
> + priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv) {
> + dev_err(host->dev, "mem alloc failed for private data\n");
> + return -ENOMEM;
> + }
> +
> + for (idx = 0; idx < ARRAY_SIZE(exynos_compat); idx++) {
> + if (of_device_is_compatible(host->dev->of_node,
> + exynos_compat[idx].compatible))
> + priv->ctrl_type = exynos_compat[idx].ctrl_type;
> + }
> +
> + host->priv = priv;
> + return 0;
> +}
> +
> +static int dw_mci_exynos_setup_clock(struct dw_mci *host)
> +{
> + struct dw_mci_exynos_priv_data *priv = host->priv;
> +
It assume that initial bus_hz is from clk_get_rate.
Can it be ensured? If value of bus_hz is set from platform, calculation is 
wrong below.

> + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5250)
> + host->bus_hz /= (priv->ciu_div + 1);
> + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412)
> + host->bus_hz /= EXYNOS4412_FIXED_CIU_CLK_DIV;
> + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210)
> + host->bus_hz /= EXYNOS4210_FIXED_CIU_CLK_DIV;
> +
> + return 0;
Here,  returning is any meaning?
There seems to be no error case.

> +}
> +
> +static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
> +{
> + /*
> +  * Exynos4412 and Exynos5250 extends the use of CMD register with the
> +  * use of bit 29 (which is reserved on standard MSHC controllers) for
> +  * optionally bypassing the HOLD register for command and data. The
> +  * HOLD register should be bypassed in case there is no phase shift
> +  * applied on CMD/DATA that is sent to the card.
> +  */
> + if (SDMMC_CLKSEL_GET_DRV_WD3(mci_readl(host, CLKSEL)))
> + *cmdr |= SDMMC_CMD_USE_HOLD_REG;
> +}
> +
> +static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
> +{
> + struct dw_mci_exynos_priv_data *priv = host->priv;
> +
> + if (ios->timing == MMC_TIMING_UHS_DDR50)
> + mci_writel(host, CLKSEL, priv->ddr_timing);
> + else
> + mci_writel(host, CLKSEL, priv->sdr_timing);
> +}
> +
> +static int dw_mci_exynos_parse_dt(struct dw_mci *host)
> +{
> + struct dw_mci_exynos_priv_data *priv = host->priv;
> + struct device_node *np = host->dev->of_node;
> + u32 timing[3];
u32 timing[2] is enough.

Thanks,
Seungwon Jeon

> + u32 div = 0;
> + int ret;
> +
> + of_property_read_u32(np, "samsung,dw-mshc-ciu-div", &div);
> + priv->ciu_div = div;
> +
> + ret = of_property_read_u32_array(np,
> + "samsung,dw-mshc-sdr-timing", timing, 2);
> + if (ret)
> + return ret;
> +
> + priv->sdr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
> +
> + ret = of_property_read_u32_array(np,
> + "samsung,dw-mshc-ddr-timing", timing, 2);
> + if (ret)
> + return ret;
> +
> + priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
> + return 0;
> +}
> +
> +static int dw_mci_exynos_setup_bus(struct dw_mci *host,
> + struct device_node *slot_np, u8 bus_width)
> +{
> + int idx, gpio, ret;
> +
> + if (!slot_np)
> + return -EINVAL;
> +
> + /* cmd + clock + bus-width pins */
> + for (idx = 0; idx < NUM_PINS(bus_width); idx++) {
> + gpio = of_get_gpio(slot_np, idx);
> + if (!gpio_is_valid(gpio)) {
> + dev_err(host->dev, "invalid gpio: %d\n", gpio);
> + return -EINVAL;
> + }
> +
> + ret = devm_gpio_request(host->dev, gpio, "dw-mci-bus");
> + if (ret) {
> + dev_err(host->dev, "gpio [%d] request failed\n", gpio);
> + return -EBUSY;
> + }
> + }
> +
> + gpio = of_get_named_gpio(slot_np, "wp-gpios", 0);
> + if (gpio_is_valid(gpio)) {
> + if (devm_gpio_request(host->dev, gpio, "dw-mci-wp"))
> + dev_info(host->dev, "gpio [%d] request failed\n",
> + gpio);
> + } else {
> + dev_info(host->dev, "wp gpio not available");
> + host->pdata->quirks |= DW_MCI_QUIRK_NO_WRITE_PROTECT;
> + 

RE: [PATCH v4 3/3] ARM: dts: Add nodes for dw_mmc controllers for Samsung Exynos5250 platforms

2012-09-05 Thread Seungwon Jeon
On Wednesday, September 05, 2012, Thomas Abraham  
wrote:
> Add device nodes for the four instances of dw_mmc controllers in Exynos5250
> and enable instance 0 and 2 for the smdk5250 board.
> 
> Signed-off-by: Thomas Abraham 
> ---
>  arch/arm/boot/dts/exynos5250-smdk5250.dts |   57 
> +
>  arch/arm/boot/dts/exynos5250.dtsi |   32 
>  2 files changed, 89 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts 
> b/arch/arm/boot/dts/exynos5250-smdk5250.dts
> index 8a5e348..ae1cffe 100644
> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
> @@ -16,6 +16,13 @@
>   model = "SAMSUNG SMDK5250 board based on EXYNOS5250";
>   compatible = "samsung,smdk5250", "samsung,exynos5250";
> 
> + aliases {
> + mshc0 = &dwmmc_0;
> + mshc1 = &dwmmc_1;
> + mshc2 = &dwmmc_2;
> + mshc3 = &dwmmc_3;
> + };
> +
>   memory {
>   reg = <0x4000 0x8000>;
>   };
> @@ -72,6 +79,56 @@
>   status = "disabled";
>   };
> 
> + dwmmc_0: dwmmc0@1220 {
> + num-slots = <1>;
> + supports-highspeed;
> + broken-cd;
> + fifo-depth = <0x80>;
> + card-detect-delay = <200>;
> + samsung,dw-mshc-ciu-div = <3>;
> + samsung,dw-mshc-sdr-timing = <2 3 3>;
> + samsung,dw-mshc-ddr-timing = <1 2 3>;
As adding dw-mshc-ciu-div, third field of dw-mshc-ddr-timing can be removed.

Thanks,
Seungwon Jeon

> +
> + slot@0 {
> + reg = <0>;
> + bus-width = <8>;
> + gpios = <&gpc0 0 2 0 3>, <&gpc0 1 2 0 3>,
> + <&gpc1 0 2 3 3>, <&gpc1 1 2 3 3>,
> + <&gpc1 2 2 3 3>, <&gpc1 3 2 3 3>,
> + <&gpc0 3 2 3 3>, <&gpc0 4 2 3 3>,
> + <&gpc0 5 2 3 3>, <&gpc0 6 2 3 3>;
> + };
> + };
> +
> + dwmmc_1: dwmmc1@1221 {
> + status = "disabled";
> + };
> +
> + dwmmc_2: dwmmc2@1222 {
> + num-slots = <1>;
> + supports-highspeed;
> + fifo-depth = <0x80>;
> + card-detect-delay = <200>;
> + samsung,dw-mshc-ciu-div = <3>;
> + samsung,dw-mshc-sdr-timing = <2 3 3>;
> + samsung,dw-mshc-ddr-timing = <1 2 3>;
> +
> + slot@0 {
> + reg = <0>;
> + bus-width = <4>;
> + samsung,cd-pinmux-gpio = <&gpc3 2 2 3 3>;
> + gpios = <&gpc3 0 2 0 3>, <&gpc3 1 2 0 3>,
> + <&gpc3 3 2 3 3>, <&gpc3 4 2 3 3>,
> + <&gpc3 5 2 3 3>, <&gpc3 6 2 3 3>,
> + <&gpc4 3 3 3 3>, <&gpc4 3 3 3 3>,
> + <&gpc4 5 3 3 3>, <&gpc4 6 3 3 3>;
> + };
> + };
> +
> + dwmmc_3: dwmmc3@1223 {
> + status = "disabled";
> + };
> +
>   spi_0: spi@12d2 {
>   status = "disabled";
>   };
> diff --git a/arch/arm/boot/dts/exynos5250.dtsi 
> b/arch/arm/boot/dts/exynos5250.dtsi
> index 004aaa8..f69e389 100644
> --- a/arch/arm/boot/dts/exynos5250.dtsi
> +++ b/arch/arm/boot/dts/exynos5250.dtsi
> @@ -182,6 +182,38 @@
>   #size-cells = <0>;
>   };
> 
> + dwmmc0@1220 {
> + compatible = "samsung,exynos5250-dw-mshc";
> + reg = <0x1220 0x1000>;
> + interrupts = <0 75 0>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + dwmmc1@1221 {
> + compatible = "samsung,exynos5250-dw-mshc";
> + reg = <0x1221 0x1000>;
> + interrupts = <0 76 0>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + dwmmc2@1222 {
> + compatible = "samsung,exynos5250-dw-mshc";
> + reg = <0x1222 0x1000>;
> + interrupts = <0 77 0

RE: [PATCH v5 9/9] mmc: dw_mmc: add support for exynos specific implementation of dw-mshc

2012-09-07 Thread Seungwon Jeon
On Friday, September 07, 2012, Thomas Abraham  wrote:
> Hi Seungwon,
> 
> Thanks for reviewing the patch.
> 
> On 5 September 2012 16:13, Seungwon Jeon  wrote:
> > On Wednesday, September 05, 2012, Thomas Abraham 
> >  wrote:
> > Version 6 is right?
> >
> >> Samsung Exynos SoC's extend the dw-mshc controller for additional clock 
> >> and bus
> >> control. Add support for these extensions and include provide device tree 
> >> based
> >> discovery suppory as well.
> >>
> >> Signed-off-by: Thomas Abraham 
> >> Acked-by: Will Newton 
> >> ---
> >>  .../devicetree/bindings/mmc/exynos-dw-mshc.txt |   86 +++
> >>  drivers/mmc/host/Kconfig   |9 +
> >>  drivers/mmc/host/Makefile  |1 +
> >>  drivers/mmc/host/dw_mmc-exynos.c   |  253 
> >> 
> >>  4 files changed, 349 insertions(+), 0 deletions(-)
> >>  create mode 100644 
> >> Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
> >>  create mode 100644 drivers/mmc/host/dw_mmc-exynos.c
> >>
> >> diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
> >> b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
> >> new file mode 100644
> >> index 000..323a891
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
> >> @@ -0,0 +1,86 @@
> >> +* Samsung Exynos specific extensions to the Synopsis Designware Mobile
> >> +  Storage Host Controller
> >> +
> >> +The Synopsis designware mobile storage host controller is used to 
> >> interface
> >> +a SoC with storage medium such as eMMC or SD/MMC cards. This file 
> >> documents
> >> +differences between the core Synopsis dw mshc controller properties 
> >> described
> >> +by synposis-dw-mshc.txt and the properties used by the Samsung Exynos 
> >> specific
> >> +extensions to the Synopsis Designware Mobile Storage Host Controller.
> >> +
> >> +Required Properties:
> >> +
> >> +* compatible: should be
> >> + - "samsung,exynos4210-dw-mshc": for controllers with Samsung 
> >> Exynos4210
> >> +   specific extentions.
> >> + - "samsung,exynos4412-dw-mshc": for controllers with Samsung 
> >> Exynos4412
> >> +   specific extentions.
> >> + - "samsung,exynos5250-dw-mshc": for controllers with Samsung 
> >> Exynos5250
> >> +   specific extentions.
> >> +
> >> +* samsung,dw-mshc-ciu-div: Specifies the divider value for the card 
> >> interface
> >> +  unit (ciu) clock. This property is applicable only for Exynos5 SoC's and
> >> +  ignored for Exynos4 SoC's. The valid range of divider value is 0 to 7.
> >> +
> >> +* samsung,dw-mshc-sdr-timing: Specifies the value of CIU clock phase 
> >> shift value
> >> +  in transmit mode and CIU clock phase shift value in receive mode for 
> >> single
> >> +  data rate mode operation. Refer notes below for the order of the cells 
> >> and the
> >> +  valid values.
> >> +
> >> +* samsung,dw-mshc-ddr-timing: Specifies the value of CUI clock phase 
> >> shift value
> >> +  in transmit mode and CIU clock phase shift value in receive mode for 
> >> double
> >> +  data rate mode operation. Refer notes below for the order of the cells 
> >> and the
> >> +  valid values.
> >> +
> >> +  Notes for the sdr-timing and ddr-timing values:
> >> +
> >> +The order of the cells should be
> >> +  - First Cell: CIU clock phase shift value for tx mode.
> >> +  - Second Cell: CIU clock phase shift value for rx mode.
> >> +
> >> +Valid values for SDR and DDR CIU clock timing for Exynos5250:
> >> +  - valid value for tx phase shift and rx phase shift is 0 to 7.
> >> +  - when CIU clock divider value is set to 3, all possible 8 phase 
> >> shift
> >> +values can be used.
> >> +  - if CIU clock divider value is 0 (that is divide by 1), both tx 
> >> and rx
> >> +phase shift clocks should be 0.
> >> +
> >> +Required properties for a slot:
> >> +
> >> +* gpios: specifies a list of gpios used for command, clock and data bus. 
> >> The
> >> +  first gpio is the command line and the second gpio is the cl

  1   2   >