All of lore.kernel.org
 help / color / mirror / Atom feed
* mmc: sdhci stop SDCLK during asynchronous interrupt peroid
@ 2011-01-05  9:39 zhangfei gao
  2011-01-05 16:30 ` Philip Rakity
  0 siblings, 1 reply; 6+ messages in thread
From: zhangfei gao @ 2011-01-05  9:39 UTC (permalink / raw)
  To: linux-mmc; +Cc: Chris Ball, Linus Walleij

>From 7554ead744bfdc7304a7ae9fb227212bf548161a Mon Sep 17 00:00:00 2001
From: Zhangfei Gao <zhangfei.gao@marvell.com>
Date: Wed, 5 Jan 2011 17:21:00 -0500
Subject: [PATCH] mmc: sdhci stop SDCLK during asynchronous interrupt peroid

	V3 controller could stop SDCLK during asynchronous interrupt peroid
to save power, via set SDHCI_CTRL2_AINT bit 14 of
SDHCI_HOST_CONTROL2(0x3e)
	Two conditions:
	1. card support asynchronous interrupt
	2. Asynchronous interrupt support is set to 1 in the capabilities register.

	How to enable: mmc->caps |= MMC_CAP_CLOCK_GATE

Signed-off-by: Zhangfei Gao <zhangfei.gao@marvell.com>
---
 drivers/mmc/host/sdhci.c |   14 ++++++++++++++
 drivers/mmc/host/sdhci.h |    2 ++
 include/linux/mmc/host.h |    2 ++
 3 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index aafbb42..946b947 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1261,6 +1261,15 @@ static void sdhci_set_ios(struct mmc_host *mmc,
struct mmc_ios *ios)
 	if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
 		sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);

+	if (mmc->caps & MMC_CAP_CLOCK_GATE) {
+		u16 con;
+
+		con = readw(host->ioaddr + SDHCI_HOST_CONTROL2);
+		con |= SDHCI_CTRL2_AINT;
+		writew(con, host->ioaddr + SDHCI_HOST_CONTROL2);
+	}
+
+
 out:
 	mmiowb();
 	spin_unlock_irqrestore(&host->lock, flags);
@@ -1808,6 +1817,11 @@ int sdhci_add_host(struct sdhci_host *host)
 			mmc->caps |= (MMC_CAP_1_8V_DDR);
 	}

+	if (mmc->caps & MMC_CAP_CLOCK_GATE) {
+		if (!(caps & SDHCI_CAN_ASYN_INT))
+			mmc->caps &= ~MMC_CAP_CLOCK_GATE;
+	}
+
 	if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
 		host->flags |= SDHCI_USE_SDMA;
 	else if (!(caps & SDHCI_CAN_DO_SDMA))
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index c4bd5dd..907de87 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -153,6 +153,7 @@
 #define   SDHCI_CTRL2_SDR104	0x0003
 #define   SDHCI_CTRL2_DDR50	0x0004
 #define  SDHCI_CTRL2_1_8V	0x0008
+#define  SDHCI_CTRL2_AINT	0x4000

 #define SDHCI_CAPABILITIES	0x40
 #define  SDHCI_TIMEOUT_CLK_MASK	0x0000003F
@@ -172,6 +173,7 @@
 #define  SDHCI_CAN_VDD_300	0x02000000
 #define  SDHCI_CAN_VDD_180	0x04000000
 #define  SDHCI_CAN_64BIT	0x10000000
+#define  SDHCI_CAN_ASYN_INT	0x20000000

 #define SDHCI_CAPABILITIES_1	0x44
 #define  SDHCI_CAN_SDR50	0x00000001
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index bcb793e..2a53a94 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -173,6 +173,8 @@ struct mmc_host {
 						/* DDR mode at 1.2V */
 #define MMC_CAP_POWER_OFF_CARD	(1 << 13)	/* Can power off after boot */
 #define MMC_CAP_BUS_WIDTH_TEST	(1 << 14)	/* CMD14/CMD19 bus width ok */
+#define MMC_CAP_CLOCK_GATE	(1 << 15)	/* V3 controller */
+						/* support clock gating */

 	mmc_pm_flag_t		pm_caps;	/* supported pm features */

-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: mmc: sdhci stop SDCLK during asynchronous interrupt peroid
  2011-01-05  9:39 mmc: sdhci stop SDCLK during asynchronous interrupt peroid zhangfei gao
@ 2011-01-05 16:30 ` Philip Rakity
  2011-01-06 10:44   ` zhangfei gao
  2011-01-09 16:34   ` Pierre Tardy
  0 siblings, 2 replies; 6+ messages in thread
From: Philip Rakity @ 2011-01-05 16:30 UTC (permalink / raw)
  To: zhangfei gao; +Cc: linux-mmc, Chris Ball, Linus Walleij


On Jan 5, 2011, at 1:39 AM, zhangfei gao wrote:

> From 7554ead744bfdc7304a7ae9fb227212bf548161a Mon Sep 17 00:00:00 2001
> From: Zhangfei Gao <zhangfei.gao@marvell.com>
> Date: Wed, 5 Jan 2011 17:21:00 -0500
> Subject: [PATCH] mmc: sdhci stop SDCLK during asynchronous interrupt peroid
> 
> 	V3 controller could stop SDCLK during asynchronous interrupt peroid
> to save power, via set SDHCI_CTRL2_AINT bit 14 of
> SDHCI_HOST_CONTROL2(0x3e)
> 	Two conditions:
> 	1. card support asynchronous interrupt
> 	2. Asynchronous interrupt support is set to 1 in the capabilities register.
> 
> 	How to enable: mmc->caps |= MMC_CAP_CLOCK_GATE
> 
> Signed-off-by: Zhangfei Gao <zhangfei.gao@marvell.com>
> ---
> drivers/mmc/host/sdhci.c |   14 ++++++++++++++
> drivers/mmc/host/sdhci.h |    2 ++
> include/linux/mmc/host.h |    2 ++
> 3 files changed, 18 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index aafbb42..946b947 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1261,6 +1261,15 @@ static void sdhci_set_ios(struct mmc_host *mmc,
> struct mmc_ios *ios)
> 	if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
> 		sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
> 
> +	if (mmc->caps & MMC_CAP_CLOCK_GATE) {
> +		u16 con;
> +
> +		con = readw(host->ioaddr + SDHCI_HOST_CONTROL2);
> +		con |= SDHCI_CTRL2_AINT;
> +		writew(con, host->ioaddr + SDHCI_HOST_CONTROL2);
> +	}
> +
> +


This will enable clock gating for SD/eMMC and SDIO cards.  This is not a good idea for SDIO where
there are known issues.  This is one reason the software clock gating code does not enable
clock gating on SDIO.  Not all SDIO cards can work.

It does not handle the case clock gating being supported in pre SD 3.0 controllers.

See my patch on h/w clock gating -- if there are issues with the patch would appreciate comments.

> out:
> 	mmiowb();
> 	spin_unlock_irqrestore(&host->lock, flags);
> @@ -1808,6 +1817,11 @@ int sdhci_add_host(struct sdhci_host *host)
> 			mmc->caps |= (MMC_CAP_1_8V_DDR);
> 	}
> 
> +	if (mmc->caps & MMC_CAP_CLOCK_GATE) {
> +		if (!(caps & SDHCI_CAN_ASYN_INT))
> +			mmc->caps &= ~MMC_CAP_CLOCK_GATE;
> +	}
> +
> 	if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
> 		host->flags |= SDHCI_USE_SDMA;
> 	else if (!(caps & SDHCI_CAN_DO_SDMA))
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index c4bd5dd..907de87 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -153,6 +153,7 @@
> #define   SDHCI_CTRL2_SDR104	0x0003
> #define   SDHCI_CTRL2_DDR50	0x0004
> #define  SDHCI_CTRL2_1_8V	0x0008
> +#define  SDHCI_CTRL2_AINT	0x4000
> 
> #define SDHCI_CAPABILITIES	0x40
> #define  SDHCI_TIMEOUT_CLK_MASK	0x0000003F
> @@ -172,6 +173,7 @@
> #define  SDHCI_CAN_VDD_300	0x02000000
> #define  SDHCI_CAN_VDD_180	0x04000000
> #define  SDHCI_CAN_64BIT	0x10000000
> +#define  SDHCI_CAN_ASYN_INT	0x20000000
> 
> #define SDHCI_CAPABILITIES_1	0x44
> #define  SDHCI_CAN_SDR50	0x00000001
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index bcb793e..2a53a94 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -173,6 +173,8 @@ struct mmc_host {
> 						/* DDR mode at 1.2V */
> #define MMC_CAP_POWER_OFF_CARD	(1 << 13)	/* Can power off after boot */
> #define MMC_CAP_BUS_WIDTH_TEST	(1 << 14)	/* CMD14/CMD19 bus width ok */
> +#define MMC_CAP_CLOCK_GATE	(1 << 15)	/* V3 controller */
> +						/* support clock gating */
> 
> 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
> 
> -- 
> 1.7.0.4
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: mmc: sdhci stop SDCLK during asynchronous interrupt peroid
  2011-01-05 16:30 ` Philip Rakity
@ 2011-01-06 10:44   ` zhangfei gao
  2011-01-06 15:52     ` Philip Rakity
  2011-01-09 16:34   ` Pierre Tardy
  1 sibling, 1 reply; 6+ messages in thread
From: zhangfei gao @ 2011-01-06 10:44 UTC (permalink / raw)
  To: Philip Rakity; +Cc: linux-mmc, Chris Ball, Linus Walleij

On Wed, Jan 5, 2011 at 11:30 AM, Philip Rakity <prakity@marvell.com> wrote:
>
> On Jan 5, 2011, at 1:39 AM, zhangfei gao wrote:
>
>> From 7554ead744bfdc7304a7ae9fb227212bf548161a Mon Sep 17 00:00:00 2001
>> From: Zhangfei Gao <zhangfei.gao@marvell.com>
>> Date: Wed, 5 Jan 2011 17:21:00 -0500
>> Subject: [PATCH] mmc: sdhci stop SDCLK during asynchronous interrupt peroid
>>
>>       V3 controller could stop SDCLK during asynchronous interrupt peroid
>> to save power, via set SDHCI_CTRL2_AINT bit 14 of
>> SDHCI_HOST_CONTROL2(0x3e)
>>       Two conditions:
>>       1. card support asynchronous interrupt
>>       2. Asynchronous interrupt support is set to 1 in the capabilities register.
>>
>>       How to enable: mmc->caps |= MMC_CAP_CLOCK_GATE
>>
>> Signed-off-by: Zhangfei Gao <zhangfei.gao@marvell.com>
>> ---
>> drivers/mmc/host/sdhci.c |   14 ++++++++++++++
>> drivers/mmc/host/sdhci.h |    2 ++
>> include/linux/mmc/host.h |    2 ++
>> 3 files changed, 18 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>> index aafbb42..946b947 100644
>> --- a/drivers/mmc/host/sdhci.c
>> +++ b/drivers/mmc/host/sdhci.c
>> @@ -1261,6 +1261,15 @@ static void sdhci_set_ios(struct mmc_host *mmc,
>> struct mmc_ios *ios)
>>       if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
>>               sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
>>
>> +     if (mmc->caps & MMC_CAP_CLOCK_GATE) {
>> +             u16 con;
>> +
>> +             con = readw(host->ioaddr + SDHCI_HOST_CONTROL2);
>> +             con |= SDHCI_CTRL2_AINT;
>> +             writew(con, host->ioaddr + SDHCI_HOST_CONTROL2);
>> +     }
>> +
>> +
>
>
> This will enable clock gating for SD/eMMC and SDIO cards.  This is not a good idea for SDIO where
> there are known issues.  This is one reason the software clock gating code does not enable
> clock gating on SDIO.  Not all SDIO cards can work.

It is enabled only by setting caps MMC_CAP_CLOCK_GATE, for example the
code to verify emmc/sd in sdhci-pxa.c

        if (pdata && pdata->flags & PXA_FLAG_CONTROL_CLK_GATE) {
                /* v3 controller could support clock gating */
                host->mmc->caps |= MMC_CAP_CLOCK_GATE;
        }
SDIO is not enabled since no PXA_FLAG_CONTROL_CLK_GATE in flags.
In the experiment, we find sdio (wifi) power does not change a lot
with or without clock gate, it mainly rely on wifi itself, for example
wifi goto deep sleep mode.

>
> It does not handle the case clock gating being supported in pre SD 3.0 controllers.
It is true, soft clock gating also be verified in SD 2.0 controller,
such as pxa955.

>
> See my patch on h/w clock gating -- if there are issues with the patch would appreciate comments.
>
>> out:
>>       mmiowb();
>>       spin_unlock_irqrestore(&host->lock, flags);
>> @@ -1808,6 +1817,11 @@ int sdhci_add_host(struct sdhci_host *host)
>>                       mmc->caps |= (MMC_CAP_1_8V_DDR);
>>       }
>>
>> +     if (mmc->caps & MMC_CAP_CLOCK_GATE) {
>> +             if (!(caps & SDHCI_CAN_ASYN_INT))
>> +                     mmc->caps &= ~MMC_CAP_CLOCK_GATE;
>> +     }
>> +
>>       if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
>>               host->flags |= SDHCI_USE_SDMA;
>>       else if (!(caps & SDHCI_CAN_DO_SDMA))
>> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
>> index c4bd5dd..907de87 100644
>> --- a/drivers/mmc/host/sdhci.h
>> +++ b/drivers/mmc/host/sdhci.h
>> @@ -153,6 +153,7 @@
>> #define   SDHCI_CTRL2_SDR104  0x0003
>> #define   SDHCI_CTRL2_DDR50   0x0004
>> #define  SDHCI_CTRL2_1_8V     0x0008
>> +#define  SDHCI_CTRL2_AINT    0x4000
>>
>> #define SDHCI_CAPABILITIES    0x40
>> #define  SDHCI_TIMEOUT_CLK_MASK       0x0000003F
>> @@ -172,6 +173,7 @@
>> #define  SDHCI_CAN_VDD_300    0x02000000
>> #define  SDHCI_CAN_VDD_180    0x04000000
>> #define  SDHCI_CAN_64BIT      0x10000000
>> +#define  SDHCI_CAN_ASYN_INT  0x20000000
>>
>> #define SDHCI_CAPABILITIES_1  0x44
>> #define  SDHCI_CAN_SDR50      0x00000001
>> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
>> index bcb793e..2a53a94 100644
>> --- a/include/linux/mmc/host.h
>> +++ b/include/linux/mmc/host.h
>> @@ -173,6 +173,8 @@ struct mmc_host {
>>                                               /* DDR mode at 1.2V */
>> #define MMC_CAP_POWER_OFF_CARD        (1 << 13)       /* Can power off after boot */
>> #define MMC_CAP_BUS_WIDTH_TEST        (1 << 14)       /* CMD14/CMD19 bus width ok */
>> +#define MMC_CAP_CLOCK_GATE   (1 << 15)       /* V3 controller */
>> +                                             /* support clock gating */
>>
>>       mmc_pm_flag_t           pm_caps;        /* supported pm features */
>>
>> --
>> 1.7.0.4
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: mmc: sdhci stop SDCLK during asynchronous interrupt peroid
  2011-01-06 10:44   ` zhangfei gao
@ 2011-01-06 15:52     ` Philip Rakity
  2011-01-07 10:29       ` zhangfei gao
  0 siblings, 1 reply; 6+ messages in thread
From: Philip Rakity @ 2011-01-06 15:52 UTC (permalink / raw)
  To: zhangfei gao; +Cc: linux-mmc, Chris Ball, Linus Walleij


On Jan 6, 2011, at 2:44 AM, zhangfei gao wrote:

> On Wed, Jan 5, 2011 at 11:30 AM, Philip Rakity <prakity@marvell.com> wrote:
>> 
>> On Jan 5, 2011, at 1:39 AM, zhangfei gao wrote:
>> 
>>> From 7554ead744bfdc7304a7ae9fb227212bf548161a Mon Sep 17 00:00:00 2001
>>> From: Zhangfei Gao <zhangfei.gao@marvell.com>
>>> Date: Wed, 5 Jan 2011 17:21:00 -0500
>>> Subject: [PATCH] mmc: sdhci stop SDCLK during asynchronous interrupt peroid
>>> 
>>>       V3 controller could stop SDCLK during asynchronous interrupt peroid
>>> to save power, via set SDHCI_CTRL2_AINT bit 14 of
>>> SDHCI_HOST_CONTROL2(0x3e)
>>>       Two conditions:
>>>       1. card support asynchronous interrupt
>>>       2. Asynchronous interrupt support is set to 1 in the capabilities register.
>>> 
>>>       How to enable: mmc->caps |= MMC_CAP_CLOCK_GATE
>>> 
>>> Signed-off-by: Zhangfei Gao <zhangfei.gao@marvell.com>
>>> ---
>>> drivers/mmc/host/sdhci.c |   14 ++++++++++++++
>>> drivers/mmc/host/sdhci.h |    2 ++
>>> include/linux/mmc/host.h |    2 ++
>>> 3 files changed, 18 insertions(+), 0 deletions(-)
>>> 
>>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>>> index aafbb42..946b947 100644
>>> --- a/drivers/mmc/host/sdhci.c
>>> +++ b/drivers/mmc/host/sdhci.c
>>> @@ -1261,6 +1261,15 @@ static void sdhci_set_ios(struct mmc_host *mmc,
>>> struct mmc_ios *ios)
>>>       if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
>>>               sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
>>> 
>>> +     if (mmc->caps & MMC_CAP_CLOCK_GATE) {
>>> +             u16 con;
>>> +
>>> +             con = readw(host->ioaddr + SDHCI_HOST_CONTROL2);
>>> +             con |= SDHCI_CTRL2_AINT;
>>> +             writew(con, host->ioaddr + SDHCI_HOST_CONTROL2);
>>> +     }
>>> +
>>> +
>> 
>> 
>> This will enable clock gating for SD/eMMC and SDIO cards.  This is not a good idea for SDIO where
>> there are known issues.  This is one reason the software clock gating code does not enable
>> clock gating on SDIO.  Not all SDIO cards can work.
> 
> It is enabled only by setting caps MMC_CAP_CLOCK_GATE, for example the
> code to verify emmc/sd in sdhci-pxa.c
> 
>        if (pdata && pdata->flags & PXA_FLAG_CONTROL_CLK_GATE) {
>                /* v3 controller could support clock gating */
>                host->mmc->caps |= MMC_CAP_CLOCK_GATE;
>        }
> SDIO is not enabled since no PXA_FLAG_CONTROL_CLK_GATE in flags.
> In the experiment, we find sdio (wifi) power does not change a lot
> with or without clock gate, it mainly rely on wifi itself, for example
> wifi goto deep sleep mode.
> 

how do you know what card will be plugged in ?  this only works work hard wired cards not for cards plugged into a slot.

>> 
>> It does not handle the case clock gating being supported in pre SD 3.0 controllers.
> It is true, soft clock gating also be verified in SD 2.0 controller,
> such as pxa955.
> 
>> 
>> See my patch on h/w clock gating -- if there are issues with the patch would appreciate comments.
>> 
>>> out:
>>>       mmiowb();
>>>       spin_unlock_irqrestore(&host->lock, flags);
>>> @@ -1808,6 +1817,11 @@ int sdhci_add_host(struct sdhci_host *host)
>>>                       mmc->caps |= (MMC_CAP_1_8V_DDR);
>>>       }
>>> 
>>> +     if (mmc->caps & MMC_CAP_CLOCK_GATE) {
>>> +             if (!(caps & SDHCI_CAN_ASYN_INT))
>>> +                     mmc->caps &= ~MMC_CAP_CLOCK_GATE;
>>> +     }
>>> +
>>>       if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
>>>               host->flags |= SDHCI_USE_SDMA;
>>>       else if (!(caps & SDHCI_CAN_DO_SDMA))
>>> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
>>> index c4bd5dd..907de87 100644
>>> --- a/drivers/mmc/host/sdhci.h
>>> +++ b/drivers/mmc/host/sdhci.h
>>> @@ -153,6 +153,7 @@
>>> #define   SDHCI_CTRL2_SDR104  0x0003
>>> #define   SDHCI_CTRL2_DDR50   0x0004
>>> #define  SDHCI_CTRL2_1_8V     0x0008
>>> +#define  SDHCI_CTRL2_AINT    0x4000
>>> 
>>> #define SDHCI_CAPABILITIES    0x40
>>> #define  SDHCI_TIMEOUT_CLK_MASK       0x0000003F
>>> @@ -172,6 +173,7 @@
>>> #define  SDHCI_CAN_VDD_300    0x02000000
>>> #define  SDHCI_CAN_VDD_180    0x04000000
>>> #define  SDHCI_CAN_64BIT      0x10000000
>>> +#define  SDHCI_CAN_ASYN_INT  0x20000000
>>> 
>>> #define SDHCI_CAPABILITIES_1  0x44
>>> #define  SDHCI_CAN_SDR50      0x00000001
>>> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
>>> index bcb793e..2a53a94 100644
>>> --- a/include/linux/mmc/host.h
>>> +++ b/include/linux/mmc/host.h
>>> @@ -173,6 +173,8 @@ struct mmc_host {
>>>                                               /* DDR mode at 1.2V */
>>> #define MMC_CAP_POWER_OFF_CARD        (1 << 13)       /* Can power off after boot */
>>> #define MMC_CAP_BUS_WIDTH_TEST        (1 << 14)       /* CMD14/CMD19 bus width ok */
>>> +#define MMC_CAP_CLOCK_GATE   (1 << 15)       /* V3 controller */
>>> +                                             /* support clock gating */
>>> 
>>>       mmc_pm_flag_t           pm_caps;        /* supported pm features */
>>> 
>>> --
>>> 1.7.0.4
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> 
>> 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: mmc: sdhci stop SDCLK during asynchronous interrupt peroid
  2011-01-06 15:52     ` Philip Rakity
@ 2011-01-07 10:29       ` zhangfei gao
  0 siblings, 0 replies; 6+ messages in thread
From: zhangfei gao @ 2011-01-07 10:29 UTC (permalink / raw)
  To: Philip Rakity; +Cc: linux-mmc, Chris Ball, Linus Walleij

On Thu, Jan 6, 2011 at 10:52 AM, Philip Rakity <prakity@marvell.com> wrote:
>
> On Jan 6, 2011, at 2:44 AM, zhangfei gao wrote:
>
>> On Wed, Jan 5, 2011 at 11:30 AM, Philip Rakity <prakity@marvell.com> wrote:
>>>
>>> On Jan 5, 2011, at 1:39 AM, zhangfei gao wrote:
>>>
>>>> From 7554ead744bfdc7304a7ae9fb227212bf548161a Mon Sep 17 00:00:00 2001
>>>> From: Zhangfei Gao <zhangfei.gao@marvell.com>
>>>> Date: Wed, 5 Jan 2011 17:21:00 -0500
>>>> Subject: [PATCH] mmc: sdhci stop SDCLK during asynchronous interrupt peroid
>>>>
>>>>       V3 controller could stop SDCLK during asynchronous interrupt peroid
>>>> to save power, via set SDHCI_CTRL2_AINT bit 14 of
>>>> SDHCI_HOST_CONTROL2(0x3e)
>>>>       Two conditions:
>>>>       1. card support asynchronous interrupt
>>>>       2. Asynchronous interrupt support is set to 1 in the capabilities register.
>>>>
>>>>       How to enable: mmc->caps |= MMC_CAP_CLOCK_GATE
>>>>
>>>> Signed-off-by: Zhangfei Gao <zhangfei.gao@marvell.com>
>>>> ---
>>>> drivers/mmc/host/sdhci.c |   14 ++++++++++++++
>>>> drivers/mmc/host/sdhci.h |    2 ++
>>>> include/linux/mmc/host.h |    2 ++
>>>> 3 files changed, 18 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>>>> index aafbb42..946b947 100644
>>>> --- a/drivers/mmc/host/sdhci.c
>>>> +++ b/drivers/mmc/host/sdhci.c
>>>> @@ -1261,6 +1261,15 @@ static void sdhci_set_ios(struct mmc_host *mmc,
>>>> struct mmc_ios *ios)
>>>>       if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
>>>>               sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
>>>>
>>>> +     if (mmc->caps & MMC_CAP_CLOCK_GATE) {
>>>> +             u16 con;
>>>> +
>>>> +             con = readw(host->ioaddr + SDHCI_HOST_CONTROL2);
>>>> +             con |= SDHCI_CTRL2_AINT;
>>>> +             writew(con, host->ioaddr + SDHCI_HOST_CONTROL2);
>>>> +     }
>>>> +
>>>> +
>>>
>>>
>>> This will enable clock gating for SD/eMMC and SDIO cards.  This is not a good idea for SDIO where
>>> there are known issues.  This is one reason the software clock gating code does not enable
>>> clock gating on SDIO.  Not all SDIO cards can work.
>>
>> It is enabled only by setting caps MMC_CAP_CLOCK_GATE, for example the
>> code to verify emmc/sd in sdhci-pxa.c
>>
>>        if (pdata && pdata->flags & PXA_FLAG_CONTROL_CLK_GATE) {
>>                /* v3 controller could support clock gating */
>>                host->mmc->caps |= MMC_CAP_CLOCK_GATE;
>>        }
>> SDIO is not enabled since no PXA_FLAG_CONTROL_CLK_GATE in flags.
>> In the experiment, we find sdio (wifi) power does not change a lot
>> with or without clock gate, it mainly rely on wifi itself, for example
>> wifi goto deep sleep mode.
>>
>
> how do you know what card will be plugged in ?  this only works work hard wired cards not for cards plugged into a slot.

The SDCLK is only stopped during asynchronous interrupt peroid, it has
some clks delay after synchronous mode, according to spec, 8 clks is
needed.
So mmc, sd card should meet the requirement, but sdio may not since the variety.
Have test emmc/sd.

>
>>>
>>> It does not handle the case clock gating being supported in pre SD 3.0 controllers.
>> It is true, soft clock gating also be verified in SD 2.0 controller,
>> such as pxa955.
>>
>>>
>>> See my patch on h/w clock gating -- if there are issues with the patch would appreciate comments.
>>>
>>>> out:
>>>>       mmiowb();
>>>>       spin_unlock_irqrestore(&host->lock, flags);
>>>> @@ -1808,6 +1817,11 @@ int sdhci_add_host(struct sdhci_host *host)
>>>>                       mmc->caps |= (MMC_CAP_1_8V_DDR);
>>>>       }
>>>>
>>>> +     if (mmc->caps & MMC_CAP_CLOCK_GATE) {
>>>> +             if (!(caps & SDHCI_CAN_ASYN_INT))
>>>> +                     mmc->caps &= ~MMC_CAP_CLOCK_GATE;
>>>> +     }
>>>> +
>>>>       if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
>>>>               host->flags |= SDHCI_USE_SDMA;
>>>>       else if (!(caps & SDHCI_CAN_DO_SDMA))
>>>> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
>>>> index c4bd5dd..907de87 100644
>>>> --- a/drivers/mmc/host/sdhci.h
>>>> +++ b/drivers/mmc/host/sdhci.h
>>>> @@ -153,6 +153,7 @@
>>>> #define   SDHCI_CTRL2_SDR104  0x0003
>>>> #define   SDHCI_CTRL2_DDR50   0x0004
>>>> #define  SDHCI_CTRL2_1_8V     0x0008
>>>> +#define  SDHCI_CTRL2_AINT    0x4000
>>>>
>>>> #define SDHCI_CAPABILITIES    0x40
>>>> #define  SDHCI_TIMEOUT_CLK_MASK       0x0000003F
>>>> @@ -172,6 +173,7 @@
>>>> #define  SDHCI_CAN_VDD_300    0x02000000
>>>> #define  SDHCI_CAN_VDD_180    0x04000000
>>>> #define  SDHCI_CAN_64BIT      0x10000000
>>>> +#define  SDHCI_CAN_ASYN_INT  0x20000000
>>>>
>>>> #define SDHCI_CAPABILITIES_1  0x44
>>>> #define  SDHCI_CAN_SDR50      0x00000001
>>>> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
>>>> index bcb793e..2a53a94 100644
>>>> --- a/include/linux/mmc/host.h
>>>> +++ b/include/linux/mmc/host.h
>>>> @@ -173,6 +173,8 @@ struct mmc_host {
>>>>                                               /* DDR mode at 1.2V */
>>>> #define MMC_CAP_POWER_OFF_CARD        (1 << 13)       /* Can power off after boot */
>>>> #define MMC_CAP_BUS_WIDTH_TEST        (1 << 14)       /* CMD14/CMD19 bus width ok */
>>>> +#define MMC_CAP_CLOCK_GATE   (1 << 15)       /* V3 controller */
>>>> +                                             /* support clock gating */
>>>>
>>>>       mmc_pm_flag_t           pm_caps;        /* supported pm features */
>>>>
>>>> --
>>>> 1.7.0.4
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>>
>
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: mmc: sdhci stop SDCLK during asynchronous interrupt peroid
  2011-01-05 16:30 ` Philip Rakity
  2011-01-06 10:44   ` zhangfei gao
@ 2011-01-09 16:34   ` Pierre Tardy
  1 sibling, 0 replies; 6+ messages in thread
From: Pierre Tardy @ 2011-01-09 16:34 UTC (permalink / raw)
  To: Philip Rakity; +Cc: zhangfei gao, linux-mmc, Chris Ball, Linus Walleij

> This will enable clock gating for SD/eMMC and SDIO cards.  This is not a good idea for SDIO where
> there are known issues.  This is one reason the software clock gating code does not enable
> clock gating on SDIO.  Not all SDIO cards can work.

See the patch I just posted on the list. I added support for software
clockgating.
"mmc: add MMC_QUIRK_BROKEN_CLK_GATING"
This one might base on this quirk to detect if the connected sdio card
can be clockgated.


Regards,
Pierre

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-01-09 16:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-05  9:39 mmc: sdhci stop SDCLK during asynchronous interrupt peroid zhangfei gao
2011-01-05 16:30 ` Philip Rakity
2011-01-06 10:44   ` zhangfei gao
2011-01-06 15:52     ` Philip Rakity
2011-01-07 10:29       ` zhangfei gao
2011-01-09 16:34   ` Pierre Tardy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.