* [PATCH] mmc: mmci: Improve runtime PM support @ 2011-10-21 15:25 Ulf Hansson 2011-10-21 17:36 ` Russell King - ARM Linux 0 siblings, 1 reply; 24+ messages in thread From: Ulf Hansson @ 2011-10-21 15:25 UTC (permalink / raw) To: linux-arm-kernel Runtime PM support is now dynamically controling the enable/disable of the clock and vcore regulator. In runtime_suspend the register values are saved and in runtime_resume register values are restored. We also make use of the runtime_autosuspend with a timeout value set to 50 ms. Moreover a runtime_idle function is implemented to be able to enter runtime suspend state after probe and when no requests are recieved from the mmc framework (due to that there are no card inserted). Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com> --- drivers/mmc/host/mmci.c | 154 ++++++++++++++++++++++++++++++++++++++--------- drivers/mmc/host/mmci.h | 6 ++- 2 files changed, 131 insertions(+), 29 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 50b5f99..571834a 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -166,14 +166,10 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) host->mrq = NULL; host->cmd = NULL; - /* - * Need to drop the host lock here; mmc_request_done may call - * back into the driver... - */ - spin_unlock(&host->lock); - pm_runtime_put(mmc_dev(host->mmc)); mmc_request_done(host->mmc, mrq); - spin_lock(&host->lock); + + pm_runtime_mark_last_busy(host->mmc->parent); + pm_runtime_put_autosuspend(host->mmc->parent); } static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) @@ -986,7 +982,7 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) return; } - pm_runtime_get_sync(mmc_dev(mmc)); + pm_runtime_get_sync(mmc->parent); spin_lock_irqsave(&host->lock, flags); @@ -1010,6 +1006,8 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) unsigned long flags; int ret; + pm_runtime_get_sync(mmc->parent); + switch (ios->power_mode) { case MMC_POWER_OFF: if (host->vcc) @@ -1058,12 +1056,15 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) mmci_set_clkreg(host, ios->clock); - if (host->pwr != pwr) { - host->pwr = pwr; + if (host->pwr_reg != pwr) { + host->pwr_reg = pwr; writel(pwr, host->base + MMCIPOWER); } spin_unlock_irqrestore(&host->lock, flags); + + pm_runtime_mark_last_busy(mmc->parent); + pm_runtime_put_autosuspend(mmc->parent); } static int mmci_get_ro(struct mmc_host *mmc) @@ -1147,6 +1148,9 @@ static int __devinit mmci_probe(struct amba_device *dev, host->gpio_wp = -ENOSYS; host->gpio_cd = -ENOSYS; host->gpio_cd_irq = -1; + host->irqmask0_reg = 0; + host->pwr_reg = 0; + host->clk_reg = 0; host->hw_designer = amba_manf(dev); host->hw_revision = amba_rev(dev); @@ -1324,6 +1328,7 @@ static int __devinit mmci_probe(struct amba_device *dev, goto irq0_free; } + host->irqmask0_reg = MCI_IRQENABLE; writel(MCI_IRQENABLE, host->base + MMCIMASK0); amba_set_drvdata(dev, mmc); @@ -1335,7 +1340,9 @@ static int __devinit mmci_probe(struct amba_device *dev, mmci_dma_setup(host); - pm_runtime_put(&dev->dev); + pm_runtime_set_autosuspend_delay(mmc->parent, 50); + pm_runtime_use_autosuspend(mmc->parent); + pm_runtime_put(mmc->parent); mmc_add_host(mmc); @@ -1377,10 +1384,11 @@ static int __devexit mmci_remove(struct amba_device *dev) struct mmci_host *host = mmc_priv(mmc); /* - * Undo pm_runtime_put() in probe. We use the _sync - * version here so that we can access the primecell. + * Make sure the host is resumed and undo the + * pm_runtime_put in probe. */ - pm_runtime_get_sync(&dev->dev); + pm_runtime_resume(mmc->parent); + pm_runtime_get_noresume(mmc->parent); mmc_remove_host(mmc); @@ -1419,43 +1427,134 @@ static int __devexit mmci_remove(struct amba_device *dev) return 0; } -#ifdef CONFIG_PM -static int mmci_suspend(struct amba_device *dev, pm_message_t state) +#ifdef CONFIG_SUSPEND + +#ifdef CONFIG_PM_RUNTIME +static void mmci_disable_irq(struct mmci_host *host) {} +static void mmci_enable_irq(struct mmci_host *host) {} +#else +static void mmci_disable_irq(struct mmci_host *host) { - struct mmc_host *mmc = amba_get_drvdata(dev); + writel(0, host->base + MMCIMASK0); +} +static void mmci_enable_irq(struct mmci_host *host) +{ + writel(host->irqmask0_reg, host->base + MMCIMASK0); +} +#endif + +static int mmci_suspend(struct device *dev) +{ + struct amba_device *adev = to_amba_device(dev); + struct mmc_host *mmc = amba_get_drvdata(adev); int ret = 0; if (mmc) { struct mmci_host *host = mmc_priv(mmc); + pm_runtime_get_sync(mmc->parent); + ret = mmc_suspend_host(mmc); - if (ret == 0) - writel(0, host->base + MMCIMASK0); + if (!ret) + mmci_disable_irq(host); + + pm_runtime_put_sync_suspend(mmc->parent); } return ret; } -static int mmci_resume(struct amba_device *dev) +static int mmci_resume(struct device *dev) { - struct mmc_host *mmc = amba_get_drvdata(dev); + struct amba_device *adev = to_amba_device(dev); + struct mmc_host *mmc = amba_get_drvdata(adev); int ret = 0; if (mmc) { struct mmci_host *host = mmc_priv(mmc); - writel(MCI_IRQENABLE, host->base + MMCIMASK0); - + mmci_enable_irq(host); ret = mmc_resume_host(mmc); } return ret; } -#else -#define mmci_suspend NULL -#define mmci_resume NULL #endif +#ifdef CONFIG_PM_RUNTIME +static int mmci_runtime_suspend(struct device *dev) +{ + struct amba_device *adev = to_amba_device(dev); + struct mmc_host *mmc = amba_get_drvdata(adev); + unsigned long flags; + + if (mmc) { + struct mmci_host *host = mmc_priv(mmc); + + spin_lock_irqsave(&host->lock, flags); + + /* Save registers for POWER, CLOCK and IRQMASK0 */ + host->irqmask0_reg = readl(host->base + MMCIMASK0); + host->pwr_reg = readl(host->base + MMCIPOWER); + host->clk_reg = readl(host->base + MMCICLOCK); + + /* + * Make sure we do not get any interrupts when we disabled the + * clock and the regulator and as well make sure to clear the + * registers for clock and power. + */ + writel(0, host->base + MMCIMASK0); + writel(0, host->base + MMCIPOWER); + writel(0, host->base + MMCICLOCK); + + spin_unlock_irqrestore(&host->lock, flags); + + clk_disable(host->clk); + amba_vcore_disable(adev); + } + + return 0; +} + +static int mmci_runtime_resume(struct device *dev) +{ + struct amba_device *adev = to_amba_device(dev); + struct mmc_host *mmc = amba_get_drvdata(adev); + unsigned long flags; + + if (mmc) { + struct mmci_host *host = mmc_priv(mmc); + + amba_vcore_enable(adev); + clk_enable(host->clk); + + spin_lock_irqsave(&host->lock, flags); + + /* Restore registers for POWER, CLOCK and IRQMASK0 */ + writel(host->clk_reg, host->base + MMCICLOCK); + writel(host->pwr_reg, host->base + MMCIPOWER); + writel(host->irqmask0_reg, host->base + MMCIMASK0); + + spin_unlock_irqrestore(&host->lock, flags); + } + + return 0; +} + +static int mmci_runtime_idle(struct device *dev) +{ + pm_runtime_suspend(dev); + return 0; +} +#endif + +static const struct dev_pm_ops mmci_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume) + SET_RUNTIME_PM_OPS(mmci_runtime_suspend, + mmci_runtime_resume, + mmci_runtime_idle) +}; + static struct amba_id mmci_ids[] = { { .id = 0x00041180, @@ -1499,11 +1598,10 @@ static struct amba_id mmci_ids[] = { static struct amba_driver mmci_driver = { .drv = { .name = DRIVER_NAME, + .pm = &mmci_dev_pm_ops, }, .probe = mmci_probe, .remove = __devexit_p(mmci_remove), - .suspend = mmci_suspend, - .resume = mmci_resume, .id_table = mmci_ids, }; diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 79e4143..4ae0f84 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -189,7 +189,6 @@ struct mmci_host { unsigned int mclk; unsigned int cclk; - u32 pwr; struct mmci_platform_data *plat; struct variant_data *variant; @@ -199,6 +198,11 @@ struct mmci_host { struct timer_list timer; unsigned int oldstat; + /* register cache */ + u32 irqmask0_reg; + u32 pwr_reg; + u32 clk_reg; + /* pio stuff */ struct sg_mapping_iter sg_miter; unsigned int size; -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-21 15:25 [PATCH] mmc: mmci: Improve runtime PM support Ulf Hansson @ 2011-10-21 17:36 ` Russell King - ARM Linux [not found] ` <CAKnu2MrOriMzJH9NcwUivWa0cinASa6wrRf4a69si4WUs-aTrQ@mail.gmail.com> 0 siblings, 1 reply; 24+ messages in thread From: Russell King - ARM Linux @ 2011-10-21 17:36 UTC (permalink / raw) To: linux-arm-kernel On Fri, Oct 21, 2011 at 05:25:54PM +0200, Ulf Hansson wrote: > +#ifdef CONFIG_PM_RUNTIME > +static int mmci_runtime_suspend(struct device *dev) > +{ > + struct amba_device *adev = to_amba_device(dev); > + struct mmc_host *mmc = amba_get_drvdata(adev); > + unsigned long flags; > + > + if (mmc) { > + struct mmci_host *host = mmc_priv(mmc); > + > + spin_lock_irqsave(&host->lock, flags); > + > + /* Save registers for POWER, CLOCK and IRQMASK0 */ > + host->irqmask0_reg = readl(host->base + MMCIMASK0); > + host->pwr_reg = readl(host->base + MMCIPOWER); > + host->clk_reg = readl(host->base + MMCICLOCK); > + > + /* > + * Make sure we do not get any interrupts when we disabled the > + * clock and the regulator and as well make sure to clear the > + * registers for clock and power. > + */ > + writel(0, host->base + MMCIMASK0); > + writel(0, host->base + MMCIPOWER); > + writel(0, host->base + MMCICLOCK); Err, no. You're not allowed to power down the card between commands unless the card has been removed or been has finished with. If you power down the card (which you _are_ doing by writing zero to the MMCIPOWER register), then you have to do a full setup of the card when you resume. This is completely unsuitable for runtime-PM usage. ^ permalink raw reply [flat|nested] 24+ messages in thread
[parent not found: <CAKnu2MrOriMzJH9NcwUivWa0cinASa6wrRf4a69si4WUs-aTrQ@mail.gmail.com>]
* [PATCH] mmc: mmci: Improve runtime PM support [not found] ` <CAKnu2MrOriMzJH9NcwUivWa0cinASa6wrRf4a69si4WUs-aTrQ@mail.gmail.com> @ 2011-10-23 0:31 ` Sebastian Rasmussen 2011-10-24 8:05 ` Ulf Hansson 2011-10-24 9:36 ` Russell King - ARM Linux 0 siblings, 2 replies; 24+ messages in thread From: Sebastian Rasmussen @ 2011-10-23 0:31 UTC (permalink / raw) To: linux-arm-kernel Hi! > Err, no. You're not allowed to power down the card between commands > unless the card has been removed or been has finished with. > > If you power down the card (which you _are_ doing by writing zero to > the MMCIPOWER register), then you have to do a full setup of the card > when you resume. MCIPower is according to ARM PL180 TRM signalling to an external power supply to turn on/off (MCIPWR), whether to use open-drain (MCIROD), what voltage to use (MCIVDD) and whether the card is clocked (MCICLK). According ST-Ericsson's public PL180 derivative spec[1] it seems to work roughly in same way (but renaming the register SDI_PWR and the signals SDIPWR & SDICLK). However, there is no SDIVDD as the derivative can not signal desired voltage level externally (there are no bits in SDI_PWR for this). This makes it plausible that SDIPWR may not be routed externally either. Can you verify this as there are no signal routing diagrams in the spec..? This leads me to believe that writing 0 to SDI_PWR/MMC in actual practice doesn't really do much but disabling the clock to the card (and for ST-Ericsson's PL180, disable direction signalling to the external level shifter). Clearing bit 8 of MCIClock/SDI_CLKCR also disables the clock. I guess the patch would appeal more to Russell if mmci_runtime_suspend() only cleared MCIMask0/SDI_MASK0 and MCIClock/SDI_CLKCR and left MCIPower/SDI_PWR unchanged. It may be the case that the signal direction bits need to be cleared for the ST-Ericsson PL180, but I haven't yet verified this on my Snowball dev board yet. / Sebastian [1] http://www.stericsson.com/developers/DM00030004_AP9500_reference_manual_rev1.pdf ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-23 0:31 ` Sebastian Rasmussen @ 2011-10-24 8:05 ` Ulf Hansson 2011-10-24 9:04 ` Russell King - ARM Linux ` (2 more replies) 2011-10-24 9:36 ` Russell King - ARM Linux 1 sibling, 3 replies; 24+ messages in thread From: Ulf Hansson @ 2011-10-24 8:05 UTC (permalink / raw) To: linux-arm-kernel Sebastian Rasmussen wrote: > Hi! > >> Err, no. You're not allowed to power down the card between commands >> unless the card has been removed or been has finished with. >> >> If you power down the card (which you _are_ doing by writing zero to >> the MMCIPOWER register), then you have to do a full setup of the card >> when you resume. > > MCIPower is according to ARM PL180 TRM signalling to an external power > supply to turn on/off (MCIPWR), whether to use open-drain (MCIROD), > what voltage to use (MCIVDD) and whether the card is clocked (MCICLK). > > According ST-Ericsson's public PL180 derivative spec[1] it seems to work > roughly in same way (but renaming the register SDI_PWR and the signals > SDIPWR & SDICLK). However, there is no SDIVDD as the derivative can not > signal desired voltage level externally (there are no bits in SDI_PWR for this). > This makes it plausible that SDIPWR may not be routed externally either. > Can you verify this as there are no signal routing diagrams in the spec..? > The hole idea with this PM patch is to make sure the vcore regulator and the clock are disabled in runtime_suspend to be able to save a huge amount of current in "idle" mode. Disabling the vcore regulator will sooner or later (depending on your regulator tree) mean that that power to the controller is actually cut, which then means that all registers will be "cleared" including the MCIPWR. So the actual reason for clearing the registers in the runtime_suspend function is because of two reasons. 1. Set the controller in a known state so no "magic" things happens when we are runtime suspended, for example getting an IRQ. 2. Save power by disabling the clock etc. The actual power to the controller does not have to be cut just because we have disabled the vore regulator. If the ARM PL180 TRM prevent us from from doing this kind of operations in runtime_suspend, we must think of an alternative solution which just apply for ST-Ericssons derivative of PL180. THIS IS VERY IMPORTANT to be able to implement a proper power management solution. Please check this Russell, this is VERY IMPORTANT! > This leads me to believe that writing 0 to SDI_PWR/MMC in actual practice > doesn't really do much but disabling the clock to the card (and for > ST-Ericsson's PL180, disable direction signalling to the external level > shifter). Clearing bit 8 of MCIClock/SDI_CLKCR also disables the clock. > > I guess the patch would appeal more to Russell if mmci_runtime_suspend() > only cleared MCIMask0/SDI_MASK0 and MCIClock/SDI_CLKCR and left > MCIPower/SDI_PWR unchanged. It may be the case that the signal direction > bits need to be cleared for the ST-Ericsson PL180, but I haven't yet verified > this on my Snowball dev board yet. This is according the comment above not feasible, since the vcore regulator to the controller is disabled all registers will be "cleared" anyway. > > / Sebastian > > [1] http://www.stericsson.com/developers/DM00030004_AP9500_reference_manual_rev1.pdf > BR Ulf Hansson ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 8:05 ` Ulf Hansson @ 2011-10-24 9:04 ` Russell King - ARM Linux 2011-10-24 9:36 ` Ulf Hansson 2011-10-24 9:11 ` Sebastian Rasmussen 2011-10-24 9:14 ` Linus Walleij 2 siblings, 1 reply; 24+ messages in thread From: Russell King - ARM Linux @ 2011-10-24 9:04 UTC (permalink / raw) To: linux-arm-kernel On Mon, Oct 24, 2011 at 10:05:30AM +0200, Ulf Hansson wrote: > Sebastian Rasmussen wrote: >> Hi! >> >>> Err, no. You're not allowed to power down the card between commands >>> unless the card has been removed or been has finished with. >>> >>> If you power down the card (which you _are_ doing by writing zero to >>> the MMCIPOWER register), then you have to do a full setup of the card >>> when you resume. >> >> MCIPower is according to ARM PL180 TRM signalling to an external power >> supply to turn on/off (MCIPWR), whether to use open-drain (MCIROD), >> what voltage to use (MCIVDD) and whether the card is clocked (MCICLK). >> >> According ST-Ericsson's public PL180 derivative spec[1] it seems to work >> roughly in same way (but renaming the register SDI_PWR and the signals >> SDIPWR & SDICLK). However, there is no SDIVDD as the derivative can not >> signal desired voltage level externally (there are no bits in SDI_PWR for this). >> This makes it plausible that SDIPWR may not be routed externally either. >> Can you verify this as there are no signal routing diagrams in the spec..? >> > > The hole idea with this PM patch is to make sure the vcore regulator and > the clock are disabled in runtime_suspend to be able to save a huge > amount of current in "idle" mode. > > Disabling the vcore regulator will sooner or later (depending on your > regulator tree) mean that that power to the controller is actually cut, > which then means that all registers will be "cleared" including the > MCIPWR. So the actual reason for clearing the registers in the > runtime_suspend function is because of two reasons. > > 1. Set the controller in a known state so no "magic" things happens when > we are runtime suspended, for example getting an IRQ. > > 2. Save power by disabling the clock etc. The actual power to the > controller does not have to be cut just because we have disabled the > vore regulator. > > If the ARM PL180 TRM prevent us from from doing this kind of operations > in runtime_suspend, we must think of an alternative solution which just > apply for ST-Ericssons derivative of PL180. THIS IS VERY IMPORTANT to be > able to implement a proper power management solution. > > Please check this Russell, this is VERY IMPORTANT! I repeat: if you cut power to the card, you have to re-initialize it. Re-initialization takes quite a bit of time to re-detect and setup the card. You'd also need to re-configure things like the transfer mode and so forth. The other problem is if you're doing runtime-pm between commands, the re-initialization takes multiple commands - we don't want to be in the middle of a reinitialization while we're also doing something with runtime-pm - nested initialization would not be a nice problem to solve. ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 9:04 ` Russell King - ARM Linux @ 2011-10-24 9:36 ` Ulf Hansson 2011-10-24 9:42 ` Russell King - ARM Linux 0 siblings, 1 reply; 24+ messages in thread From: Ulf Hansson @ 2011-10-24 9:36 UTC (permalink / raw) To: linux-arm-kernel Russell King - ARM Linux wrote: > On Mon, Oct 24, 2011 at 10:05:30AM +0200, Ulf Hansson wrote: >> Sebastian Rasmussen wrote: >>> Hi! >>> >>>> Err, no. You're not allowed to power down the card between commands >>>> unless the card has been removed or been has finished with. >>>> >>>> If you power down the card (which you _are_ doing by writing zero to >>>> the MMCIPOWER register), then you have to do a full setup of the card >>>> when you resume. >>> MCIPower is according to ARM PL180 TRM signalling to an external power >>> supply to turn on/off (MCIPWR), whether to use open-drain (MCIROD), >>> what voltage to use (MCIVDD) and whether the card is clocked (MCICLK). >>> >>> According ST-Ericsson's public PL180 derivative spec[1] it seems to work >>> roughly in same way (but renaming the register SDI_PWR and the signals >>> SDIPWR & SDICLK). However, there is no SDIVDD as the derivative can not >>> signal desired voltage level externally (there are no bits in SDI_PWR for this). >>> This makes it plausible that SDIPWR may not be routed externally either. >>> Can you verify this as there are no signal routing diagrams in the spec..? >>> >> The hole idea with this PM patch is to make sure the vcore regulator and >> the clock are disabled in runtime_suspend to be able to save a huge >> amount of current in "idle" mode. >> >> Disabling the vcore regulator will sooner or later (depending on your >> regulator tree) mean that that power to the controller is actually cut, >> which then means that all registers will be "cleared" including the >> MCIPWR. So the actual reason for clearing the registers in the >> runtime_suspend function is because of two reasons. >> >> 1. Set the controller in a known state so no "magic" things happens when >> we are runtime suspended, for example getting an IRQ. >> >> 2. Save power by disabling the clock etc. The actual power to the >> controller does not have to be cut just because we have disabled the >> vore regulator. >> >> If the ARM PL180 TRM prevent us from from doing this kind of operations >> in runtime_suspend, we must think of an alternative solution which just >> apply for ST-Ericssons derivative of PL180. THIS IS VERY IMPORTANT to be >> able to implement a proper power management solution. >> >> Please check this Russell, this is VERY IMPORTANT! > > I repeat: if you cut power to the card, you have to re-initialize it. > Re-initialization takes quite a bit of time to re-detect and setup > the card. You'd also need to re-configure things like the transfer > mode and so forth. Right now host->vcc (vmmc) regulator is controlling the power to card. Not the MCIPWR register! It is possible for ARM PL180 trm (not for STE version) to use MCIPWR to control some external regulator. But right now, this is not used according the code and it also feels like a very strange setup. I would be very surprised if any hardware has this kind of setup, that the PL180 itself controls a regulator. > > The other problem is if you're doing runtime-pm between commands, > the re-initialization takes multiple commands - we don't want to be > in the middle of a reinitialization while we're also doing something > with runtime-pm - nested initialization would not be a nice problem > to solve. > You do not have to re-init the card as long at is still powered. It is just a matter of restoring register values. This is really quick. But at the same time, we do not want to do it for every request thus we use timeout of 50 ms. ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 9:36 ` Ulf Hansson @ 2011-10-24 9:42 ` Russell King - ARM Linux 2011-10-24 10:06 ` Ulf Hansson 0 siblings, 1 reply; 24+ messages in thread From: Russell King - ARM Linux @ 2011-10-24 9:42 UTC (permalink / raw) To: linux-arm-kernel On Mon, Oct 24, 2011 at 11:36:01AM +0200, Ulf Hansson wrote: > Russell King - ARM Linux wrote: >> I repeat: if you cut power to the card, you have to re-initialize it. >> Re-initialization takes quite a bit of time to re-detect and setup >> the card. You'd also need to re-configure things like the transfer >> mode and so forth. > > Right now host->vcc (vmmc) regulator is controlling the power to card. > Not the MCIPWR register! Maybe for you, but that's not the case on all platforms. You *really* need to get out of the idea that just because your implementation works one way that everything works that way. You're working on a cross-SoC cross-platform driver, and you need to take account of how other platforms work. In that case, there *are* platforms which the MCIPWR register does indeed control power to the card - and setting this to zero _will_ power down the card. > I would be very surprised if any hardware has this kind of setup, that > the PL180 itself controls a regulator. ARM dev boards all use the MCIPWR bits to control an external power switch - there's no adjustment of the voltage except via soldered links on the board. ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 9:42 ` Russell King - ARM Linux @ 2011-10-24 10:06 ` Ulf Hansson 2011-10-24 10:14 ` Russell King - ARM Linux 0 siblings, 1 reply; 24+ messages in thread From: Ulf Hansson @ 2011-10-24 10:06 UTC (permalink / raw) To: linux-arm-kernel Russell King - ARM Linux wrote: > On Mon, Oct 24, 2011 at 11:36:01AM +0200, Ulf Hansson wrote: >> Russell King - ARM Linux wrote: >>> I repeat: if you cut power to the card, you have to re-initialize it. >>> Re-initialization takes quite a bit of time to re-detect and setup >>> the card. You'd also need to re-configure things like the transfer >>> mode and so forth. >> Right now host->vcc (vmmc) regulator is controlling the power to card. >> Not the MCIPWR register! > > Maybe for you, but that's not the case on all platforms. > > You *really* need to get out of the idea that just because your > implementation works one way that everything works that way. You're > working on a cross-SoC cross-platform driver, and you need to take > account of how other platforms work. Sorry for being a pain in the ass. :-) I am thinking of the above, even if it not seems like that. > > In that case, there *are* platforms which the MCIPWR register does > indeed control power to the card - and setting this to zero _will_ > power down the card. > >> I would be very surprised if any hardware has this kind of setup, that >> the PL180 itself controls a regulator. > > ARM dev boards all use the MCIPWR bits to control an external power > switch - there's no adjustment of the voltage except via soldered > links on the board. That explains it! My believe was that since the bits for controlling the voltage levels etc was not used (which is replaced with directions bits for ST-version), this functionality was not used either. Could you maybe elaborate a bit of how the power is controlled in the ARM dev boards? Would it be possible to control such a switch in "GPIO" manner instead? For example via the vdd_handler or similar? I will also think if and see if is feasible to re-design and see if this hole feature can be controlled by the variant struct instead. My feeling is although it can be kind of messy. But let's see... BR Ulf Hansson ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 10:06 ` Ulf Hansson @ 2011-10-24 10:14 ` Russell King - ARM Linux 2011-10-24 11:48 ` Ulf Hansson 0 siblings, 1 reply; 24+ messages in thread From: Russell King - ARM Linux @ 2011-10-24 10:14 UTC (permalink / raw) To: linux-arm-kernel On Mon, Oct 24, 2011 at 12:06:27PM +0200, Ulf Hansson wrote: > Russell King - ARM Linux wrote: >> On Mon, Oct 24, 2011 at 11:36:01AM +0200, Ulf Hansson wrote: >>> Russell King - ARM Linux wrote: >>>> I repeat: if you cut power to the card, you have to re-initialize it. >>>> Re-initialization takes quite a bit of time to re-detect and setup >>>> the card. You'd also need to re-configure things like the transfer >>>> mode and so forth. >>> Right now host->vcc (vmmc) regulator is controlling the power to >>> card. Not the MCIPWR register! >> >> Maybe for you, but that's not the case on all platforms. >> >> You *really* need to get out of the idea that just because your >> implementation works one way that everything works that way. You're >> working on a cross-SoC cross-platform driver, and you need to take >> account of how other platforms work. > > Sorry for being a pain in the ass. :-) I am thinking of the above, even > if it not seems like that. > >> >> In that case, there *are* platforms which the MCIPWR register does >> indeed control power to the card - and setting this to zero _will_ >> power down the card. >> >>> I would be very surprised if any hardware has this kind of setup, >>> that the PL180 itself controls a regulator. >> >> ARM dev boards all use the MCIPWR bits to control an external power >> switch - there's no adjustment of the voltage except via soldered >> links on the board. > > That explains it! > > My believe was that since the bits for controlling the voltage levels > etc was not used (which is replaced with directions bits for > ST-version), this functionality was not used either. > > Could you maybe elaborate a bit of how the power is controlled in the > ARM dev boards? Would it be possible to control such a switch in "GPIO" > manner instead? For example via the vdd_handler or similar? > > I will also think if and see if is feasible to re-design and see if this > hole feature can be controlled by the variant struct instead. My feeling > is although it can be kind of messy. But let's see... The MCIPWR register contains two bits to control _the_ _power_ _state_. See Table A-4: the MCIPWR signal. See section 2.2.2. See section 3.3.1. The MCIPWR signal controls the external power switch. This is the only signal for it. This is the only connection for it. There is no other control form for this power switch. ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 10:14 ` Russell King - ARM Linux @ 2011-10-24 11:48 ` Ulf Hansson 2011-10-24 12:18 ` Linus Walleij 0 siblings, 1 reply; 24+ messages in thread From: Ulf Hansson @ 2011-10-24 11:48 UTC (permalink / raw) To: linux-arm-kernel >> Could you maybe elaborate a bit of how the power is controlled in the >> ARM dev boards? Would it be possible to control such a switch in "GPIO" >> manner instead? For example via the vdd_handler or similar? >> >> I will also think if and see if is feasible to re-design and see if this >> hole feature can be controlled by the variant struct instead. My feeling >> is although it can be kind of messy. But let's see... > > The MCIPWR register contains two bits to control _the_ _power_ _state_. > See Table A-4: the MCIPWR signal. See section 2.2.2. See section 3.3.1. > > The MCIPWR signal controls the external power switch. This is the only > signal for it. This is the only connection for it. There is no other > control form for this power switch. > Then we are only left to use the variant struct I believe. In principle, a flag in the variant struct, could indicate whether it is OK to disable the vcore regulator and thus clear the MCIPWR when doing runtime_suspend. How do you feel about this kind of approach to find a solution? BR Ulf Hansson ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 11:48 ` Ulf Hansson @ 2011-10-24 12:18 ` Linus Walleij 2011-10-24 15:25 ` Ulf Hansson 0 siblings, 1 reply; 24+ messages in thread From: Linus Walleij @ 2011-10-24 12:18 UTC (permalink / raw) To: linux-arm-kernel On Mon, Oct 24, 2011 at 1:48 PM, Ulf Hansson <ulf.hansson@stericsson.com> wrote: > [Russell] >> The MCIPWR signal controls the external power switch. ?This is the only >> signal for it. ?This is the only connection for it. ?There is no other >> control form for this power switch. >> > > Then we are only left to use the variant struct I believe. In principle, a > flag in the variant struct, could indicate whether it is OK to disable the > vcore regulator and thus clear the MCIPWR when doing runtime_suspend. Yep I think the best could be to add some variant named bool external_card_power; and then document in the kerneldoc that this means the driver can clear MMCIPWR without risk of cutting the power to the card. This should be true for Ux500, U300 and Nomadik (just checked the designs - they all have external regulators). So the state save/restore and amba_vcore_disable(adev); should be done only for those variants. However this: clk_disable(host->clk); We ought to be able to do for *all* variants, provided we can create pm_runtime_get/put and delay properly to cover all bus traffic (looks like the patch already does that), plus all the time the card is signalling busy. The best I can think of is to just return -EBUSY to runtime PM like this: if ((readl(base + MMCISTATUS) & (MCI_CMDACTIVE | MCI_TXACTIVE| MCI_RXACTIVE)) return -EBUSY; Yours, Linus Walleij ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 12:18 ` Linus Walleij @ 2011-10-24 15:25 ` Ulf Hansson 2011-10-24 15:34 ` Ulf Hansson 2011-10-25 7:12 ` Linus Walleij 0 siblings, 2 replies; 24+ messages in thread From: Ulf Hansson @ 2011-10-24 15:25 UTC (permalink / raw) To: linux-arm-kernel Linus Walleij wrote: > On Mon, Oct 24, 2011 at 1:48 PM, Ulf Hansson <ulf.hansson@stericsson.com> wrote: >> [Russell] >>> The MCIPWR signal controls the external power switch. This is the only >>> signal for it. This is the only connection for it. There is no other >>> control form for this power switch. >>> >> Then we are only left to use the variant struct I believe. In principle, a >> flag in the variant struct, could indicate whether it is OK to disable the >> vcore regulator and thus clear the MCIPWR when doing runtime_suspend. > > Yep I think the best could be to add some variant named > bool external_card_power; and then document in the kerneldoc that this > means the driver can clear MMCIPWR without risk of cutting the power > to the card. > > This should be true for Ux500, U300 and Nomadik (just checked the designs - > they all have external regulators). > Could we assume that all boards which utilizes the ARM PL180 are using the MMCIPWR register to control power the card? Or should we add a new amba mmci platform member so this is configurable for each board? An option could also be if we might want to simplify code to just skip the entire runtime_suspend|idle|resume function (ie stubb it or something) for these kind of boards? What do you prefer? > So the state save/restore and amba_vcore_disable(adev); should be done > only for those variants. > > However this: > > clk_disable(host->clk); > > We ought to be able to do for *all* variants, provided we can create > pm_runtime_get/put and delay properly to cover all bus traffic > (looks like the patch already does that), plus all the time the card is > signalling busy. The best I can think of is to just return -EBUSY to runtime > PM like this: > > if ((readl(base + MMCISTATUS) & (MCI_CMDACTIVE | MCI_TXACTIVE| MCI_RXACTIVE)) > return -EBUSY; > > Yours, > Linus Walleij > ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 15:25 ` Ulf Hansson @ 2011-10-24 15:34 ` Ulf Hansson 2011-10-25 7:12 ` Linus Walleij 1 sibling, 0 replies; 24+ messages in thread From: Ulf Hansson @ 2011-10-24 15:34 UTC (permalink / raw) To: linux-arm-kernel Ulf Hansson wrote: > Linus Walleij wrote: >> On Mon, Oct 24, 2011 at 1:48 PM, Ulf Hansson <ulf.hansson@stericsson.com> wrote: >>> [Russell] >>>> The MCIPWR signal controls the external power switch. This is the only >>>> signal for it. This is the only connection for it. There is no other >>>> control form for this power switch. >>>> >>> Then we are only left to use the variant struct I believe. In principle, a >>> flag in the variant struct, could indicate whether it is OK to disable the >>> vcore regulator and thus clear the MCIPWR when doing runtime_suspend. >> Yep I think the best could be to add some variant named >> bool external_card_power; and then document in the kerneldoc that this >> means the driver can clear MMCIPWR without risk of cutting the power >> to the card. >> >> This should be true for Ux500, U300 and Nomadik (just checked the designs - >> they all have external regulators). >> > > Could we assume that all boards which utilizes the ARM PL180 are using > the MMCIPWR register to control power the card? Or should we add a new > amba mmci platform member so this is configurable for each board? > > An option could also be if we might want to simplify code to just skip > the entire runtime_suspend|idle|resume function (ie stubb it or > something) for these kind of boards? > > What do you prefer? By the way, there is also another option. In the runtime_suspend function for ARM PL180 block we can use mmc_power_save_host (and then also disable vcore etc) and vice verse in runtime_resume with mmc_power_restore_host. Of course, these kind of operations takes quite some time to execute and therefore we use a much bigger timeout than 50 ms (for example 10 s instead) for ARM PL180. Just an idea... > >> So the state save/restore and amba_vcore_disable(adev); should be done >> only for those variants. >> >> However this: >> >> clk_disable(host->clk); >> >> We ought to be able to do for *all* variants, provided we can create >> pm_runtime_get/put and delay properly to cover all bus traffic >> (looks like the patch already does that), plus all the time the card is >> signalling busy. The best I can think of is to just return -EBUSY to runtime >> PM like this: >> >> if ((readl(base + MMCISTATUS) & (MCI_CMDACTIVE | MCI_TXACTIVE| MCI_RXACTIVE)) >> return -EBUSY; >> >> Yours, >> Linus Walleij >> > > ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 15:25 ` Ulf Hansson 2011-10-24 15:34 ` Ulf Hansson @ 2011-10-25 7:12 ` Linus Walleij 2011-10-25 7:39 ` Ulf Hansson 1 sibling, 1 reply; 24+ messages in thread From: Linus Walleij @ 2011-10-25 7:12 UTC (permalink / raw) To: linux-arm-kernel 2011/10/24 Ulf Hansson <ulf.hansson@stericsson.com>: > Could we assume that all boards which utilizes the ARM PL180 are using the > MMCIPWR register to control power the card? Or should we add a new amba mmci > platform member so this is configurable for each board? I think we should take entire variants, like currently U300 and Ux500. In those designs the MMCIPWR signal is left dangling on the chip, so no-one electronics designer can use that signal for anything even if s/he would have wanted to. > An option could also be if we might want to simplify code to just skip the > entire runtime_suspend|idle|resume function (ie stubb it or something) for > these kind of boards? I think the clk_disable()/clk_enable() pair in runtime suspend/resume is still valuable for all other variants too. That has nothing to do with MMCIPWR. > By the way, there is also another option. In the runtime_suspend function > for ARM PL180 block we can use mmc_power_save_host (and then also > disable vcore etc) and vice verse in runtime_resume with > mmc_power_restore_host. This is what the OMAP driver does right? > Of course, these kind of operations takes quite some time to execute and > therefore we use a much bigger timeout than 50 ms (for example 10 s > instead) for ARM PL180. Can we do both? 1) Break out mmci_state_save_restore() from the runtime PM hooks. 2) I.e. have a short time-out that will runtime-suspend the external regulator variants quickly with finer granularity. 3) Have a long time-out that will runtime-suspend the MMCIPWR variants using mmc_power_save_host() with a longer delay? Since mmc_power_save_host() calls .set_ios() to really shut down the power to the card we should be on the safe side. Looks like a nice silver bullet to me :-) I volunteer to test the long time-out code path on the Integrator PB1176 to verify this works. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-25 7:12 ` Linus Walleij @ 2011-10-25 7:39 ` Ulf Hansson 0 siblings, 0 replies; 24+ messages in thread From: Ulf Hansson @ 2011-10-25 7:39 UTC (permalink / raw) To: linux-arm-kernel Linus Walleij wrote: > 2011/10/24 Ulf Hansson <ulf.hansson@stericsson.com>: > >> Could we assume that all boards which utilizes the ARM PL180 are using the >> MMCIPWR register to control power the card? Or should we add a new amba mmci >> platform member so this is configurable for each board? > > I think we should take entire variants, like currently U300 and Ux500. > In those designs the MMCIPWR signal is left dangling on the chip, > so no-one electronics designer can use that signal for anything even > if s/he would have wanted to. > >> An option could also be if we might want to simplify code to just skip the >> entire runtime_suspend|idle|resume function (ie stubb it or something) for >> these kind of boards? > > I think the clk_disable()/clk_enable() pair in runtime suspend/resume > is still valuable for all other variants too. That has nothing to do with > MMCIPWR. > >> By the way, there is also another option. In the runtime_suspend function >> for ARM PL180 block we can use mmc_power_save_host (and then also >> disable vcore etc) and vice verse in runtime_resume with >> mmc_power_restore_host. > > This is what the OMAP driver does right? Nope. Right now I think it is only SDIO function drivers through pm_runtime that can trigger the use of these functions though the bus registered runtime functions. > >> Of course, these kind of operations takes quite some time to execute and >> therefore we use a much bigger timeout than 50 ms (for example 10 s >> instead) for ARM PL180. > > Can we do both? That is possible! But I think we need confirmation from Russell first. Using mmc_power_save_host/mmc_power_restore_host could be a way forward for ARM PL180, but you should note that initializing a card after it has been fully powered down, can for really crappy SD-cards take up to 1 s. Normally this time is 100-400 ms. This initialization time will then be the latency for the first read/write after the runtime timeout has expired. There is always a cost in "performance" when doing power save it seems. :-) > > 1) Break out mmci_state_save_restore() from the runtime PM hooks. > > 2) I.e. have a short time-out that will runtime-suspend the external > regulator variants quickly with finer granularity. > > 3) Have a long time-out that will runtime-suspend the MMCIPWR > variants using mmc_power_save_host() with a longer delay? > Since mmc_power_save_host() calls .set_ios() to really shut > down the power to the card we should be on the safe side. > > Looks like a nice silver bullet to me :-) > > I volunteer to test the long time-out code path on the Integrator > PB1176 to verify this works. > > Yours, > Linus Walleij > ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 8:05 ` Ulf Hansson 2011-10-24 9:04 ` Russell King - ARM Linux @ 2011-10-24 9:11 ` Sebastian Rasmussen 2011-10-24 9:14 ` Linus Walleij 2 siblings, 0 replies; 24+ messages in thread From: Sebastian Rasmussen @ 2011-10-24 9:11 UTC (permalink / raw) To: linux-arm-kernel Hi! > If the ARM PL180 TRM prevent us from from doing this kind of operations in > runtime_suspend, we must think of an alternative solution which just apply > for ST-Ericssons derivative of PL180. THIS IS VERY IMPORTANT to be able to > implement a proper power management solution. I believe that what it boils down to is how the power regulators are controlled. In ST-Ericssons PL180 derivative there must be two independent regulators, controlled by something outside the PL180 itself, one for the controller and one for the external card. So if you know what you are doing you can power down the controller while still keeping the card powered. In the case of ARM PL180 it seems to me as if there is one power regulator, controlled by something outside the PL180, that supplies power to the controller, and one power regulator, controlled by the PL180, that supplies power to the card. Therefore it is simply not possible to clear the ARM PL180s MCIPower register (because that means that the card will loose power since the control signals to the card's power regulator are now asking it to cut power to the card). In addition I believe that it may not be possible to power the controller down... / Sebastian ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 8:05 ` Ulf Hansson 2011-10-24 9:04 ` Russell King - ARM Linux 2011-10-24 9:11 ` Sebastian Rasmussen @ 2011-10-24 9:14 ` Linus Walleij 2 siblings, 0 replies; 24+ messages in thread From: Linus Walleij @ 2011-10-24 9:14 UTC (permalink / raw) To: linux-arm-kernel On Mon, Oct 24, 2011 at 10:05 AM, Ulf Hansson <ulf.hansson@stericsson.com> wrote: > The hole idea with this PM patch is to make sure the vcore regulator and the > clock are disabled in runtime_suspend to be able to save a huge amount of > current in "idle" mode. > > Disabling the vcore regulator will sooner or later (depending on your > regulator tree) mean that that power to the controller is actually cut, > which then means that all registers will be "cleared" including the MCIPWR. I guess since this means writing power-off to bits 1 and 0 of of MCIPower meaning "power off" it should not be done unless the MMC core has first issued mmci_set_ios() with MMC_POWER_OFF set in ios->power_mode. Which means mmc_power_off() must have been called. That in turn is called by mmc_power_save_host() or mmc_suspend_host(). mmc_power_save_host() is in turn called by mmc_runtime_suspend() in drivers/mmc/bus.c! So if that is called *before* the driver-local runtime suspend calls, you're actually on the safe side, and you can proceed to cut the power. So these need to be zero before we enter runtime suspend. This could then be assured by: if (readl(host->base + MMCIPOWER) & 3) return -EBUSY; If this has already been done we are on the green and can runtime suspend the controller I guess? So what this code > + /* Save registers for POWER, CLOCK and IRQMASK0 */ > + host->irqmask0_reg = readl(host->base + MMCIMASK0); > + host->pwr_reg = readl(host->base + MMCIPOWER); > + host->clk_reg = readl(host->base + MMCICLOCK); In the end does is save the contents of the other 30 bits. (MCI_OD, MCI_ROD, and the ST-specific bits) So can we first: - Assure that mmc_power_save_host() has already been done (MMCI_POWER_OFF) - Make this variable a prerequiste for cutting the power in runtime_pm? Yours, Linus Walleij ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-23 0:31 ` Sebastian Rasmussen 2011-10-24 8:05 ` Ulf Hansson @ 2011-10-24 9:36 ` Russell King - ARM Linux 2011-10-24 9:54 ` Linus Walleij 1 sibling, 1 reply; 24+ messages in thread From: Russell King - ARM Linux @ 2011-10-24 9:36 UTC (permalink / raw) To: linux-arm-kernel On Sun, Oct 23, 2011 at 02:31:39AM +0200, Sebastian Rasmussen wrote: > I guess the patch would appeal more to Russell if mmci_runtime_suspend() > only cleared MCIMask0/SDI_MASK0 and MCIClock/SDI_CLKCR and left > MCIPower/SDI_PWR unchanged. It may be the case that the signal direction > bits need to be cleared for the ST-Ericsson PL180, but I haven't yet verified > this on my Snowball dev board yet. There's also the issue that the specs call for the clock to run after a command has completed for a certain number of cycles, and that the clock must continue to run until the card reports not-busy after a programming or erase cycle has completed - that can be long after the previous command has 'completed'. ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 9:36 ` Russell King - ARM Linux @ 2011-10-24 9:54 ` Linus Walleij 2011-10-24 9:56 ` Russell King - ARM Linux 0 siblings, 1 reply; 24+ messages in thread From: Linus Walleij @ 2011-10-24 9:54 UTC (permalink / raw) To: linux-arm-kernel On Mon, Oct 24, 2011 at 11:36 AM, Russell King - ARM Linux <linux@arm.linux.org.uk> wrote: > On Sun, Oct 23, 2011 at 02:31:39AM +0200, Sebastian Rasmussen wrote: >> I guess the patch would appeal more to Russell if mmci_runtime_suspend() >> only cleared MCIMask0/SDI_MASK0 and MCIClock/SDI_CLKCR and left >> MCIPower/SDI_PWR unchanged. It may be the case that the signal direction >> bits need to be cleared for the ST-Ericsson PL180, but I haven't yet verified >> this on my Snowball dev board yet. > > There's also the issue that the specs call for the clock to run after > a command has completed for a certain number of cycles, and that the > clock must continue to run until the card reports not-busy after a > programming or erase cycle has completed - that can be long after the > previous command has 'completed'. It's 8 cycles on MCLK required. I think that is taken care of by this: pm_runtime_set_autosuspend_delay(mmc->parent, 50); 50 ms is >> 8 MCLK in any practical case, but if we want to be really, really sure we can always: #define DEFAULT_DELAY 50 int delay; delay = DIV_ROUND_UP((1000 * 8), host->mclk); /* 8 MCLK in ms */ delay = max(DEFAULT_DELAY, min_delay); pm_runtime_set_autosuspend_delay(mmc->parent, delay); So we have encoded all assumptions. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 9:54 ` Linus Walleij @ 2011-10-24 9:56 ` Russell King - ARM Linux 2011-10-24 10:17 ` Ulf Hansson 2011-10-25 8:05 ` Adrian Hunter 0 siblings, 2 replies; 24+ messages in thread From: Russell King - ARM Linux @ 2011-10-24 9:56 UTC (permalink / raw) To: linux-arm-kernel On Mon, Oct 24, 2011 at 11:54:00AM +0200, Linus Walleij wrote: > On Mon, Oct 24, 2011 at 11:36 AM, Russell King - ARM Linux > <linux@arm.linux.org.uk> wrote: > > On Sun, Oct 23, 2011 at 02:31:39AM +0200, Sebastian Rasmussen wrote: > >> I guess the patch would appeal more to Russell if mmci_runtime_suspend() > >> only cleared MCIMask0/SDI_MASK0 and MCIClock/SDI_CLKCR and left > >> MCIPower/SDI_PWR unchanged. It may be the case that the signal direction > >> bits need to be cleared for the ST-Ericsson PL180, but I haven't yet verified > >> this on my Snowball dev board yet. > > > > There's also the issue that the specs call for the clock to run after > > a command has completed for a certain number of cycles, and that the > > clock must continue to run until the card reports not-busy after a > > programming or erase cycle has completed - that can be long after the > > previous command has 'completed'. > > It's 8 cycles on MCLK required. _Plus_ keeping the clock running while the card is signalling busy. If you don't clock the card while its signalling busy, it will never go non-busy (the data line becomes frozen.) ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 9:56 ` Russell King - ARM Linux @ 2011-10-24 10:17 ` Ulf Hansson 2011-10-24 11:49 ` Linus Walleij 2011-10-25 8:05 ` Adrian Hunter 1 sibling, 1 reply; 24+ messages in thread From: Ulf Hansson @ 2011-10-24 10:17 UTC (permalink / raw) To: linux-arm-kernel Russell King - ARM Linux wrote: > On Mon, Oct 24, 2011 at 11:54:00AM +0200, Linus Walleij wrote: >> On Mon, Oct 24, 2011 at 11:36 AM, Russell King - ARM Linux >> <linux@arm.linux.org.uk> wrote: >>> On Sun, Oct 23, 2011 at 02:31:39AM +0200, Sebastian Rasmussen wrote: >>>> I guess the patch would appeal more to Russell if mmci_runtime_suspend() >>>> only cleared MCIMask0/SDI_MASK0 and MCIClock/SDI_CLKCR and left >>>> MCIPower/SDI_PWR unchanged. It may be the case that the signal direction >>>> bits need to be cleared for the ST-Ericsson PL180, but I haven't yet verified >>>> this on my Snowball dev board yet. >>> There's also the issue that the specs call for the clock to run after >>> a command has completed for a certain number of cycles, and that the >>> clock must continue to run until the card reports not-busy after a >>> programming or erase cycle has completed - that can be long after the >>> previous command has 'completed'. >> It's 8 cycles on MCLK required. > > _Plus_ keeping the clock running while the card is signalling busy. > > If you don't clock the card while its signalling busy, it will never > go non-busy (the data line becomes frozen.) > Good point! Is the aggressive clk gating feature in the mmc framework taking this into account as well? Potentially the framework could do a get_sync/put (in claim/release host) to prevent hosts from being runtime disabled. Similar how the enable/disable mechanism is working. ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 10:17 ` Ulf Hansson @ 2011-10-24 11:49 ` Linus Walleij 0 siblings, 0 replies; 24+ messages in thread From: Linus Walleij @ 2011-10-24 11:49 UTC (permalink / raw) To: linux-arm-kernel On Mon, Oct 24, 2011 at 12:17 PM, Ulf Hansson <ulf.hansson@stericsson.com> wrote: > Russell King - ARM Linux wrote: >> On Mon, Oct 24, 2011 at 11:54:00AM +0200, Linus Walleij wrote: >>> >>> It's 8 cycles on MCLK required. >> >> _Plus_ keeping the clock running while the card is signalling busy. >> >> If you don't clock the card while its signalling busy, it will never >> go non-busy (the data line becomes frozen.) >> > > (...) > Is the aggressive clk gating feature in the mmc framework taking this into > account as well? Nope. That is why frequency 0 is not handled like some special case in the MMCI driver, which means you can turn it on but nothing spectacularly power saving will happen. (i.e. clock gating does not gate the clock on the mmci driver) I did a rough patch to cut the clock but Russell pointed out the problem here (same as discussed above): http://marc.info/?l=linux-mmc&m=129146545916794&w=2 I *was* meaning to fix it. However now I feel that since we're anyway ironing out the painful details of runtime PM, we can probably use that framework to handle also aggressive clock gating. > Potentially the framework could do a get_sync/put (in claim/release host) to > prevent hosts from being runtime disabled. Similar how the enable/disable > mechanism is working. Yep. We just need to make sure the hysteresis/delay value covers the bus activity with some margin. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-24 9:56 ` Russell King - ARM Linux 2011-10-24 10:17 ` Ulf Hansson @ 2011-10-25 8:05 ` Adrian Hunter 2011-10-25 8:53 ` Linus Walleij 1 sibling, 1 reply; 24+ messages in thread From: Adrian Hunter @ 2011-10-25 8:05 UTC (permalink / raw) To: linux-arm-kernel On 24/10/11 12:56, Russell King - ARM Linux wrote: > On Mon, Oct 24, 2011 at 11:54:00AM +0200, Linus Walleij wrote: >> On Mon, Oct 24, 2011 at 11:36 AM, Russell King - ARM Linux >> <linux@arm.linux.org.uk> wrote: >>> On Sun, Oct 23, 2011 at 02:31:39AM +0200, Sebastian Rasmussen wrote: >>>> I guess the patch would appeal more to Russell if mmci_runtime_suspend() >>>> only cleared MCIMask0/SDI_MASK0 and MCIClock/SDI_CLKCR and left >>>> MCIPower/SDI_PWR unchanged. It may be the case that the signal direction >>>> bits need to be cleared for the ST-Ericsson PL180, but I haven't yet verified >>>> this on my Snowball dev board yet. >>> >>> There's also the issue that the specs call for the clock to run after >>> a command has completed for a certain number of cycles, and that the >>> clock must continue to run until the card reports not-busy after a >>> programming or erase cycle has completed - that can be long after the >>> previous command has 'completed'. >> >> It's 8 cycles on MCLK required. > > _Plus_ keeping the clock running while the card is signalling busy. > > If you don't clock the card while its signalling busy, it will never > go non-busy (the data line becomes frozen.) The spec does say that it is OK to turn off the clock, but it must be turned back on to release the busy signal. That will always happen with the block driver because it always sends a status command when waiting. Maybe it is an issue with SDIO but currently SDIO is using MMC_QUIRK_BROKEN_CLK_GATING by default (although wl1271 is using it) > -- > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] mmc: mmci: Improve runtime PM support 2011-10-25 8:05 ` Adrian Hunter @ 2011-10-25 8:53 ` Linus Walleij 0 siblings, 0 replies; 24+ messages in thread From: Linus Walleij @ 2011-10-25 8:53 UTC (permalink / raw) To: linux-arm-kernel On Tue, Oct 25, 2011 at 10:05 AM, Adrian Hunter <adrian.hunter@intel.com> wrote: > The spec does say that it is OK to turn off the clock, but it > must be turned back on to release the busy signal. ?That will always > happen with the block driver because it always sends a status command > when waiting. Aha, thanks for clearing this up! > Maybe it is an issue with SDIO but currently SDIO is using > MMC_QUIRK_BROKEN_CLK_GATING by default (although wl1271 is > using it) IIRC SDIO is supposed to allow their clock to be cut, if it is a peripheral that needs constant clocking it should have its own clockline/crystal or whatever, basically. However most SDIO device engineers just see the MCLK and like "hey, clock, I'll just lock my PLL onto that sweet clock line and save the crystal..." violating the spec. In worst cases they even drive the entire logic inside the device from the MCLK line and count on it being perpetually enabled. Atleast that's how I think about it. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2011-10-25 8:53 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-21 15:25 [PATCH] mmc: mmci: Improve runtime PM support Ulf Hansson
2011-10-21 17:36 ` Russell King - ARM Linux
[not found] ` <CAKnu2MrOriMzJH9NcwUivWa0cinASa6wrRf4a69si4WUs-aTrQ@mail.gmail.com>
2011-10-23 0:31 ` Sebastian Rasmussen
2011-10-24 8:05 ` Ulf Hansson
2011-10-24 9:04 ` Russell King - ARM Linux
2011-10-24 9:36 ` Ulf Hansson
2011-10-24 9:42 ` Russell King - ARM Linux
2011-10-24 10:06 ` Ulf Hansson
2011-10-24 10:14 ` Russell King - ARM Linux
2011-10-24 11:48 ` Ulf Hansson
2011-10-24 12:18 ` Linus Walleij
2011-10-24 15:25 ` Ulf Hansson
2011-10-24 15:34 ` Ulf Hansson
2011-10-25 7:12 ` Linus Walleij
2011-10-25 7:39 ` Ulf Hansson
2011-10-24 9:11 ` Sebastian Rasmussen
2011-10-24 9:14 ` Linus Walleij
2011-10-24 9:36 ` Russell King - ARM Linux
2011-10-24 9:54 ` Linus Walleij
2011-10-24 9:56 ` Russell King - ARM Linux
2011-10-24 10:17 ` Ulf Hansson
2011-10-24 11:49 ` Linus Walleij
2011-10-25 8:05 ` Adrian Hunter
2011-10-25 8:53 ` Linus Walleij
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).