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