sdhci: runtime suspend/resume on card insert/removal
Hi,
During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.
Let me try to explain it using execution sequence -
During boot:
MMC SD card gets detected as expected.
[ 2.431012] mmc1: new high speed SDHC card at address 1234 [ 2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB [ 2.444841] mmcblk1: p1
Now after coming to the linux prompt, if card removal event occurs then the call sequence is -
sdhci_irq() -->
-> sdhci_thread_irq(): host->thread_isr - 0x80
-> sdhci_card_event()
-> mmc_detect_change()
--> _mmc_detect_change()
---> mmc_sd_detect()
mmc_sd_remove()
mmc_remove_card()
mmc_bus_remove()
mmc_power_off()
mmc_set_initial_state()
sdhci_set_ios()
...
sdhci_pxav3_runtime_suspend()
sdhci_runtime_suspend_host()Till here everything looks perfect :) (if I got it right)
Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.
But what I am observing here is, no interrupt is generated, as it is not enabled at all. And the reason being sdhci_runtime_suspend_host()
int sdhci_runtime_suspend_host(struct sdhci_host *host)
{
....
spin_lock_irqsave(&host->lock, flags);
host->ier &= SDHCI_INT_CARD_INT;
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
spin_unlock_irqrestore(&host->lock, flags);
...
}In my case, I see SDHCI_INT_CARD_INT is not ON and with above step we are not ensuring that it is enabled either.
Also we are not enabling card insertion and removal interrupts.
I have done following change to the code -
drivers/mmc/host/sdhci.c +0 -0
@@ -2783,9 +2783,12 @@ int sdhci_runtime_suspend_host(struct sdhci_host
*host)
mmc_retune_needed(host->mmc);
spin_lock_irqsave(&host->lock, flags);
- host->ier &= SDHCI_INT_CARD_INT;
+
+ host->flags |= SDHCI_SDIO_IRQ_ENABLED;
+ host->ier |= SDHCI_INT_CARD_INT;
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
+
spin_unlock_irqrestore(&host->lock, flags);
synchronize_hardirq(host->irq);And things started working as expected.
The execution sequence of irq and sdhci_runtime_resume both looks ok to me.
Card insertion event =
sdhci_irq() -->
-> sdhci_thread_irq: host->thread_isr - 40
--> sdhci_card_event()
--> mmc_detect_change()
---> _mmc_detect_change()
...
-> sdhci_pxav3_runtime_resume()
--> sdhci_do_set_ios:1438I see card getting enumerated as expected -
[ 15.116098] mmc1: mmc_rescan_try_freq: trying to init card at 400000 Hz [ 15.356473] mmc1: new high speed SDHC card at address 1234 [ 15.363962] mmcblk1: mmc1:1234 SA04G 3.63 GiB [ 15.371043] sdhci_thread_irq:2642 host->thread_isr - 100 [ 15.376492] mmcblk1: p1
I believe (based on my understanding) the change I have done is right. I am not sure how other platforms using sdhci.c working so far, probably no runtime_pm support? Not sure though
Please let me know if I am missing something here.
And not, and everyone is ok with this, I will submit the patch fixing this issue.
Thanks,
Vaibhav
Hi Vaibhav,
Quoted 37 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…
Hi,
During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.
Let me try to explain it using execution sequence -
During boot:
MMC SD card gets detected as expected.
[ 2.431012] mmc1: new high speed SDHC card at address 1234 [ 2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB [ 2.444841] mmcblk1: p1Now after coming to the linux prompt, if card removal event occurs then the call sequence is -
sdhci_irq()-->
->sdhci_thread_irq():host->thread_isr-0x80-> sdhci_card_event() -> mmc_detect_change() --> _mmc_detect_change() ---> mmc_sd_detect() mmc_sd_remove() mmc_remove_card() mmc_bus_remove() mmc_power_off() mmc_set_initial_state() sdhci_set_ios() ... sdhci_pxav3_runtime_suspend() sdhci_runtime_suspend_host()
Quoted 5 lines
Till here everything looks perfect :) (if I got it right)
Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.
AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI controller itself because SDHCI controller is runtime suspended, clk gated or power gated. So the wakeup irq should come from other always on components. Take Marvell berlin SoC as an example:
there's gpio for sdcard detect, card insertion => trigger cd gpio interrupt =>resume sdhci host etc.
If your changes work, the I guess your SDHCI host are not clk gated or power gated during runtime suspended.
Thanks,
Jisheng
Quoted 87 lines
But what I am observing here is, no interrupt is generated, as it is not enabled at all. And the reason being
sdhci_runtime_suspend_host()int
sdhci_runtime_suspend_host(struct sdhci_host *host){ .... spin_lock_irqsave(&host->lock, flags); host->ier &= SDHCI_INT_CARD_INT; sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); spin_unlock_irqrestore(&host->lock, flags); ... }In my case, I see
SDHCI_INT_CARD_INTis not ON and with above step we are not ensuring that it is enabled either.
Also we are not enabling card insertion and removal interrupts.I have done following change to the code -
drivers/mmc/host/sdhci.c +4
-1@@ -2783,9 +2783,12 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)mmc_retune_needed (host->mmc);spin_lock_irqsave (&host->lock, flags); - host->ier &=SDHCI_INT_CARD_INT ; + + host->flags |=SDHCI_SDIO_IRQ_ENABLED ; + host->ier |=SDHCI_INT_CARD_INT ;sdhci_writel (host, host->ier,SDHCI_INT_ENABLE );sdhci_writel (host, host->ier,SDHCI_SIGNAL_ENABLE ); +spin_unlock_irqrestore (&host->lock, flags);synchronize_hardirq(host->irq);And things started working as expected.
The execution sequence of irq andsdhci_runtime_resumeboth looks ok to me.Card insertion event =
sdhci_irq()-->
->sdhci_thread_irq:host->thread_isr- 40--> sdhci_card_event() --> mmc_detect_change() ---> _mmc_detect_change() ... -> sdhci_pxav3_runtime_resume() --> sdhci_do_set_ios:1438I see card getting enumerated as expected -
[ 15.116098] mmc1: mmc_rescan_try_freq: trying to init card at 400000 Hz [ 15.356473] mmc1: new high speed SDHC card at address 1234 [ 15.363962] mmcblk1: mmc1:1234 SA04G 3.63 GiB [ 15.371043] sdhci_thread_irq:2642 host->thread_isr - 100 [ 15.376492] mmcblk1: p1I believe (based on my understanding) the change I have done is right. I am not sure how other platforms using
sdhci.cworking so far, probably noruntime_pmsupport? Not sure thoughPlease let me know if I am missing something here.
And not, and everyone is ok with this, I will submit the patch fixing this issue.Thanks,
Vaibhav_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Quoted 48 lines · Jisheng Zhang
Hi Vaibhav,
Quoted 37 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…
Hi,
During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.
Let me try to explain it using execution sequence -
During boot:
MMC SD card gets detected as expected.
[ 2.431012] mmc1: new high speed SDHC card at address 1234 [ 2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB [ 2.444841] mmcblk1: p1Now after coming to the linux prompt, if card removal event occurs then the call sequence is -
sdhci_irq() --> -> sdhci_thread_irq(): host->thread_isr - 0x80 -> sdhci_card_event() -> mmc_detect_change() --> _mmc_detect_change() ---> mmc_sd_detect() mmc_sd_remove() mmc_remove_card() mmc_bus_remove() mmc_power_off() mmc_set_initial_state() sdhci_set_ios() ... sdhci_pxav3_runtime_suspend() sdhci_runtime_suspend_host()Quoted 5 lines
Till here everything looks perfect :) (if I got it right)
Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.
Quoted 7 lines
AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI controller itself because SDHCI controller is runtime suspended, clk gated or power gated. So the wakeup irq should come from other always on components. Take Marvell berlin SoC as an example:
there's gpio for sdcard detect, card insertion => trigger cd gpio interrupt =>resume sdhci host etc.
Not always.
In my case SDHCI controller is generating card insert and remove event/interrupts. Just to add here, I am not configuring any pins to GPIO mode. My pin configuration for card-detect is in MMC_CD mode.
The card insertion and removal interrupt is mapped to SDHCI interrupt line, which is interrupt number 12 in my case.
# cat /proc/interrupts
CPU0
11: 55 GIC 105 Level mmc0
12: 220 GIC 101 Level mmc1Quoted 4 lines
If your changes work, the I guess your SDHCI host are not clk gated or power gated during runtime suspended.
This is what I suspected initially, but it doesn't look that way.
Without this change, if I just disable/remove
pm_runtime_put_autosuspend(&pdev->dev);
then also it works for me. What it tells me that, if I disable runtime_pm then it works.
I can cross-check register values to make sure that it is really turned off. Let me do that as well.
Thanks,
Vaibhav
Quoted 56 lines · On Thu, 10 Sep 2015 13:21:12 +0530 Vaibhav Hiremath…
Quoted 53 lines · Jisheng Zhang
Hi Vaibhav,
Quoted 37 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…
Hi,
During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.
Let me try to explain it using execution sequence -
During boot:
MMC SD card gets detected as expected.
[ 2.431012] mmc1: new high speed SDHC card at address 1234 [ 2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB [ 2.444841] mmcblk1: p1Now after coming to the linux prompt, if card removal event occurs then the call sequence is -
sdhci_irq() --> -> sdhci_thread_irq(): host->thread_isr - 0x80 -> sdhci_card_event() -> mmc_detect_change() --> _mmc_detect_change() ---> mmc_sd_detect() mmc_sd_remove() mmc_remove_card() mmc_bus_remove() mmc_power_off() mmc_set_initial_state() sdhci_set_ios() ... sdhci_pxav3_runtime_suspend() sdhci_runtime_suspend_host()Quoted 5 lines
Till here everything looks perfect :) (if I got it right)
Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.
AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI controller itself because SDHCI controller is runtime suspended, clk gated or power gated. So the wakeup irq should come from other always on components. Take Marvell berlin SoC as an example:
Quoted 7 lines
Quoted 2 lines
there's gpio for sdcard detect, card insertion => trigger cd gpio interrupt =>resume sdhci host etc.
Not always.
In my case SDHCI controller is generating card insert and remove event/interrupts. Just to add here, I am not configuring any pins
How could sdhci controller generate card insert/remove interrupts if it's clk gated or power gated? We should have another wake up mechanism for runtime pm.
Quoted 1 line
to GPIO mode. My pin configuration for card-detect is in
MMC_CDmode.
I guess the pin is muxed between SD_CD pin and gpio.
Quoted 29 lines
The card insertion and removal interrupt is mapped to SDHCI interrupt line, which is interrupt number 12 in my case.
# cat /proc/interrupts CPU0 11: 55 GIC 105 Level mmc0 12: 220 GIC 101 Level mmc1Quoted 4 lines
If your changes work, the I guess your SDHCI host are not clk gated or power gated during runtime suspended.
This is what I suspected initially, but it doesn't look that way.
Without this change, if I just disable/remove
pm_runtime_put_autosuspend(&pdev->dev);then also it works for me. What it tells me that, if I disable
runtime_pmthen it works.I can cross-check register values to make sure that it is really turned off. Let me do that as well.
Thanks,
Vaibhav
Quoted 42 lines · Jisheng Zhang
Hi Vaibhav,
Quoted 37 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…
Hi,
During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.
Let me try to explain it using execution sequence -
During boot:
MMC SD card gets detected as expected.
[ 2.431012] mmc1: new high speed SDHC card at address 1234 [ 2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB [ 2.444841] mmcblk1: p1Now after coming to the linux prompt, if card removal event occurs then the call sequence is -
sdhci_irq()-->
->sdhci_thread_irq():host->thread_isr-0x80-> sdhci_card_event() -> mmc_detect_change() --> _mmc_detect_change() ---> mmc_sd_detect() mmc_sd_remove() mmc_remove_card() mmc_bus_remove() mmc_power_off() mmc_set_initial_state() sdhci_set_ios() ... sdhci_pxav3_runtime_suspend() sdhci_runtime_suspend_host()
Quoted 7 lines
Quoted 5 lines
Till here everything looks perfect :) (if I got it right)
Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.
AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI
Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.
Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net.
Hi Russell,
Quoted 45 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 44 lines · Jisheng Zhang
Hi Vaibhav,
Quoted 39 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…
Hi,
During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.
Let me try to explain it using execution sequence -
During boot:
MMC SD card gets detected as expected.
[ 2.431012] mmc1: new high speed SDHC card at address 1234 [ 2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB [ 2.444841] mmcblk1: p1Now after coming to the linux prompt, if card removal event occurs then the call sequence is -
sdhci_irq()-->
->sdhci_thread_irq():host->thread_isr-0x80-> sdhci_card_event() -> mmc_detect_change() --> _mmc_detect_change() ---> mmc_sd_detect() mmc_sd_remove() mmc_remove_card() mmc_bus_remove() mmc_power_off() mmc_set_initial_state() sdhci_set_ios() ... sdhci_pxav3_runtime_suspend() sdhci_runtime_suspend_host()Till here everything looks perfect :) (if I got it right)
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.
AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI
Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.
Oh, yes. Sorry for misleading, I didn't express myself clearly. What I really means is that the card insertion/remove irq which could finally cause sdhci host resumed.
Thanks for clarification,
Jisheng
Quoted 54 lines · Jisheng Zhang
Hi Russell,
Quoted 49 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 48 lines · Jisheng Zhang
Hi Vaibhav,
Quoted 42 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…
Hi,
During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.
Let me try to explain it using execution sequence -
During boot:
MMC SD card gets detected as expected.
[ 2.431012] mmc1: new high speed SDHC card at address 1234 [ 2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB [ 2.444841] mmcblk1: p1Now after coming to the linux prompt, if card removal event occurs then the call sequence is -
sdhci_irq() --> -> sdhci_thread_irq(): host->thread_isr - 0x80 -> sdhci_card_event() -> mmc_detect_change() --> _mmc_detect_change() ---> mmc_sd_detect() mmc_sd_remove() mmc_remove_card() mmc_bus_remove() mmc_power_off() mmc_set_initial_state() sdhci_set_ios() ... sdhci_pxav3_runtime_suspend() sdhci_runtime_suspend_host()Till here everything looks perfect :) (if I got it right)
Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.
Quoted 9 lines
Quoted 4 lines
Quoted 1 line
AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI
Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.
Oh, yes. Sorry for misleading, I didn't express myself clearly. What I really means is that the card insertion/remove irq which could finally cause sdhci host resumed.
So Jisheng,
You are ok with above change, right?
Thanks,
Vaibhav
Quoted 62 lines · On Mon, 14 Sep 2015 11:55:56 +0530 Vaibhav Hiremath…
Quoted 59 lines · Jisheng Zhang
Hi Russell,
Quoted 53 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 42 lines · Jisheng Zhang
Hi Vaibhav,
Quoted 37 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…
Hi,
During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.
Let me try to explain it using execution sequence -
During boot:
MMC SD card gets detected as expected.
[ 2.431012] mmc1: new high speed SDHC card at address 1234 [ 2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB [ 2.444841] mmcblk1: p1Now after coming to the linux prompt, if card removal event occurs then the call sequence is -
sdhci_irq() --> -> sdhci_thread_irq(): host->thread_isr - 0x80 -> sdhci_card_event() -> mmc_detect_change() --> _mmc_detect_change() ---> mmc_sd_detect() mmc_sd_remove() mmc_remove_card() mmc_bus_remove() mmc_power_off() mmc_set_initial_state() sdhci_set_ios() ... sdhci_pxav3_runtime_suspend() sdhci_runtime_suspend_host()Quoted 7 lines
Quoted 5 lines
Till here everything looks perfect :) (if I got it right)
Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.
AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI
Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.
Quoted 8 lines
Quoted 4 lines
Oh, yes. Sorry for misleading, I didn't express myself clearly. What I really means is that the card insertion/remove irq which could finally cause sdhci host resumed.
So Jisheng,
You are ok with above change, right?
Nope. the above is just to clarify my mixing "wakeup IRQs" and the card insertion/remove irq that brings sdhci host resumed.
IMHO, your patch is still not necessary and perhaps wrong.
Thanks,
Jisheng
Quoted 70 lines · Jisheng Zhang
Quoted 67 lines · On Mon, 14 Sep 2015 11:55:56 +0530 Vaibhav Hiremath…
Quoted 63 lines · Jisheng Zhang
Hi Russell,
Quoted 45 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 44 lines · Jisheng Zhang
Hi Vaibhav,
Quoted 39 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…
Hi,
During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.
Let me try to explain it using execution sequence -
During boot:
MMC SD card gets detected as expected.
[ 2.431012] mmc1: new high speed SDHC card at address 1234 [ 2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB [ 2.444841] mmcblk1: p1Now after coming to the linux prompt, if card removal event occurs then the call sequence is -
sdhci_irq() --> -> sdhci_thread_irq(): host->thread_isr - 0x80 -> sdhci_card_event() -> mmc_detect_change() --> _mmc_detect_change() ---> mmc_sd_detect() mmc_sd_remove() mmc_remove_card() mmc_bus_remove() mmc_power_off() mmc_set_initial_state() sdhci_set_ios() ... sdhci_pxav3_runtime_suspend() sdhci_runtime_suspend_host()Till here everything looks perfect :) (if I got it right)
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.
AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI
Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.
Oh, yes. Sorry for misleading, I didn't express myself clearly. What I really means is that the card insertion/remove irq which could finally cause sdhci host resumed.
Quoted 9 lines
Quoted 3 lines
So Jisheng,
You are ok with above change, right?
Nope. the above is just to clarify my mixing "wakeup IRQs" and the card insertion/remove irq that brings sdhci host resumed.
IMHO, your patch is still not necessary and perhaps wrong.
Don't be in hurry to conclude,
Let's understand the technical aspect fist.
Let me clarify once again here,
The card detect interrupt is coming from SDHCI controller itself, I have confirmed that the runtime PM is working perfectly fine, clock is gated/disabled on card removal.
Clock Gating:
=============
#
# devmem 0xd4282854 0x0000181B # [ 1318.948460] mmc1: card 1234 removed
#
# devmem 0xd4282854 0x00001800 #
Power from the regulator -
==========================
Only "vqmmc" stays on, and it is required for the card detection. I have confirmed it.
So my patch still makes sense.
Thanks,
Vaibhav
Quoted 83 lines · On Mon, 14 Sep 2015 13:43:32 +0530 Vaibhav Hiremath…
Quoted 70 lines · Jisheng Zhang
Quoted 67 lines · On Mon, 14 Sep 2015 11:55:56 +0530 Vaibhav Hiremath…
Quoted 63 lines · Jisheng Zhang
Hi Russell,
Quoted 45 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 44 lines · Jisheng Zhang
Hi Vaibhav,
Quoted 39 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…
Hi,
During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.
Let me try to explain it using execution sequence -
During boot:
MMC SD card gets detected as expected.
[ 2.431012] mmc1: new high speed SDHC card at address 1234 [ 2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB [ 2.444841] mmcblk1: p1Now after coming to the linux prompt, if card removal event occurs then the call sequence is -
sdhci_irq() --> -> sdhci_thread_irq(): host->thread_isr - 0x80 -> sdhci_card_event() -> mmc_detect_change() --> _mmc_detect_change() ---> mmc_sd_detect() mmc_sd_remove() mmc_remove_card() mmc_bus_remove() mmc_power_off() mmc_set_initial_state() sdhci_set_ios() ... sdhci_pxav3_runtime_suspend() sdhci_runtime_suspend_host()Till here everything looks perfect :) (if I got it right)
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.
AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI
Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.
Oh, yes. Sorry for misleading, I didn't express myself clearly. What I really means is that the card insertion/remove irq which could finally cause sdhci host resumed.
Quoted 9 lines
Quoted 3 lines
So Jisheng,
You are ok with above change, right?
Nope. the above is just to clarify my mixing "wakeup IRQs" and the card insertion/remove irq that brings sdhci host resumed.
IMHO, your patch is still not necessary and perhaps wrong.
Quoted 8 lines
Don't be in hurry to conclude,
Let's understand the technical aspect fist.Let me clarify once again here,
The card detect interrupt is coming from SDHCI controller itself,
But how the SDHCI controller generate CD interrupt when it's in runtime suspended state, i.e clock gated or power gated?
Quoted 2 lines
I have confirmed that the runtime PM is working perfectly fine, clock is gated/disabled on card removal.
But seems we still didn't know the sdhci host is clock gated or power gated.
Quoted 5 lines
Clock Gating:
=============
#
Quoted 8 lines
# devmem 0xd4282854 0x0000181B # [ 1318.948460] mmc1: card 1234 removed#
# devmem 0xd4282854 0x00001800 #
Can you plz read the SDHCI host registers after this step? If the host is clock gated, we should get "asynchronous external abort" in theory.
Thanks
Quoted 90 lines · Jisheng Zhang
Quoted 87 lines · On Mon, 14 Sep 2015 13:43:32 +0530 Vaibhav Hiremath…
Quoted 70 lines · Jisheng Zhang
Quoted 67 lines · On Mon, 14 Sep 2015 11:55:56 +0530 Vaibhav Hiremath…
Quoted 63 lines · Jisheng Zhang
Hi Russell,
Quoted 45 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 44 lines · Jisheng Zhang
Hi Vaibhav,
Quoted 39 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…
Hi,
During my testing of SDHCI-PXAV3 driver on Marvell's pxa1928 based platform, I observed that runtime PM suspend/resume is having issues with card insertion and removal.
Let me try to explain it using execution sequence -
During boot:
MMC SD card gets detected as expected.
[ 2.431012] mmc1: new high speed SDHC card at address 1234 [ 2.437235] mmcblk1: mmc1:1234 SA04G 3.63 GiB [ 2.444841] mmcblk1: p1Now after coming to the linux prompt, if card removal event occurs then the call sequence is -
sdhci_irq() --> -> sdhci_thread_irq(): host->thread_isr - 0x80 -> sdhci_card_event() -> mmc_detect_change() --> _mmc_detect_change() ---> mmc_sd_detect() mmc_sd_remove() mmc_remove_card() mmc_bus_remove() mmc_power_off() mmc_set_initial_state() sdhci_set_ios() ... sdhci_pxav3_runtime_suspend() sdhci_runtime_suspend_host()Till here everything looks perfect :) (if I got it right)
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Now on card insertion again, the expectation is, runtime resume should get called as part of interrupt trigger from the SDHCI controller on card insertion.
AFAIK, card insertion => wakeup irq, this irq doesn't come from SDHCI
Wakeup IRQs are what happens when the _system_ is in suspend, not when the device is runtime suspended.
Oh, yes. Sorry for misleading, I didn't express myself clearly. What I really means is that the card insertion/remove irq which could finally cause sdhci host resumed.
Quoted 9 lines
Quoted 3 lines
So Jisheng,
You are ok with above change, right?
Nope. the above is just to clarify my mixing "wakeup IRQs" and the card insertion/remove irq that brings sdhci host resumed.
IMHO, your patch is still not necessary and perhaps wrong.
Don't be in hurry to conclude,
Let's understand the technical aspect fist.
Quoted 8 lines
Quoted 4 lines
Let me clarify once again here,
The card detect interrupt is coming from SDHCI controller itself,
But how the SDHCI controller generate CD interrupt when it's in runtime suspended state, i.e clock gated or power gated?
Due to lack of detailed Documentation its difficult to conclude here
Quoted 5 lines
Quoted 2 lines
I have confirmed that the runtime PM is working perfectly fine, clock is gated/disabled on card removal.
But seems we still didn't know the sdhci host is clock gated or power gated.
Register above is
SDIO Host 1 Clock/Reset Control Register
And bit 3 & 4 says
BIT 3:
SD Host 1 Peripheral Clock Enable
0x1: Peripheral clock enabled
0x0: Peripheral clock disabled
BIT4:
SD Host 1 AXI Clock Enable
0x1: AXI clock enabled
0x0: AXI clock disabled
Quoted 9 lines
Quoted 9 lines
Clock Gating:
=============
## devmem 0xd4282854 0x0000181B # [ 1318.948460] mmc1: card 1234 removed
Quoted 8 lines
Quoted 4 lines
#
# devmem 0xd4282854 0x00001800 #Can you plz read the SDHCI host registers after this step? If the host is clock gated, we should get "asynchronous external abort" in theory.
Ok, that's another way. I can cross check on this.
Thanks,
Vaibhav
Quoted 28 lines · Vaibhav Hiremath
Quoted 25 lines · Jisheng Zhang
Quoted 22 lines · On Mon, 14 Sep 2015 13:43:32 +0530 Vaibhav Hiremath…
Quoted 19 lines · Jisheng Zhang
Quoted 16 lines · On Mon, 14 Sep 2015 11:55:56 +0530 Vaibhav Hiremath…
Quoted 13 lines · Jisheng Zhang
Hi Russell,
Quoted 8 lines · On Thu, 10 Sep 2015 09:02:33 +0100 Russell King - ARM Linux…
Quoted 7 lines · Jisheng Zhang
Hi Vaibhav,
Quoted 2 lines · On Thu, 10 Sep 2015 12:40:48 +0530 Vaibhav Hiremath…
Hi,
<snip>
Quoted 39 lines
Quoted 6 lines
Quoted 2 lines
I have confirmed that the runtime PM is working perfectly fine, clock is gated/disabled on card removal.
But seems we still didn't know the sdhci host is clock gated or power gated.
Register above is
SDIO Host 1 Clock/Reset Control RegisterAnd bit 3 & 4 says
BIT 3:
SD Host 1 Peripheral Clock Enable
0x1: Peripheral clock enabled
0x0: Peripheral clock disabledBIT4:
SD Host 1 AXI Clock Enable
0x1: AXI clock enabled
0x0: AXI clock disabledQuoted 14 lines
Quoted 13 lines
Clock Gating:
=============
## devmem 0xd4282854 0x0000181B # [ 1318.948460] mmc1: card 1234 removed#
# devmem 0xd4282854 0x00001800 #
Quoted 6 lines
Quoted 3 lines
Can you plz read the SDHCI host registers after this step? If the host is clock gated, we should get "asynchronous external abort" in theory.
Ok, that's another way. I can cross check on this.
Came across below lines in the datasheet,
========= Copy-n-paste from datasheet============
All SDH interfaces share the same clock which is enabled when any of the SDH clock enables are
set (from PMUA_SDH1_CLK_RES_CTRL, PMUA_SDH2_CLK_RES_CTRL, PMUA_SDH3_CLK_RES_CTRL, PMUA_SDH4_CLK_RES_CTRL, PMUA_SDH5_CLK_RES_CTRL), with clock source select and divider ratio controlled byPMUA_SDH1_CLK_RES_CTRL.
==================================================
And I can confirm that after disabling AXI interface clock for all the SDH modules (1-5) I see I get an abort.
This clearly explains/justifies/proves that the existing code is working as expected. I have eMMC mounted on the board, which makes clock to always stay ON on SDH3.
So there is an OR gate implemented inside which takes input from SDHx_AXI_EN and feeds back to all SDHx instances. Don't ask me why it has been designed that way :)
And I did some experiment as well, so what I have observed is, SDH_AXI_CLOCK is required to generate card detection, without that I do not see card detection working.
So Jisheng,
The change/patch which I was referring to now is more clear and I believe now you would realize that it is required for SDH to work on PXA1928 platform.
If you have access to internal documentation or someone who knows the design, please try to cross check.
Thanks,
Vaibhav
Quoted 22 lines · Vaibhav Hiremath
Came across below lines in the datasheet,
========= Copy-n-paste from datasheet============
All SDH interfaces share the same clock which is enabled when any of the SDH clock enables are
set (fromPMUA_SDH1_CLK_RES_CTRL,PMUA_SDH2_CLK_RES_CTRL,PMUA_SDH3_CLK_RES_CTRL,PMUA_SDH4_CLK_RES_CTRL,PMUA_SDH5_CLK_RES_CTRL), with clock source select and divider ratio controlled byPMUA_SDH1_CLK_RES_CTRL.==================================================
And I can confirm that after disabling AXI interface clock for all the SDH modules (1-5) I see I get an abort.
This clearly explains/justifies/proves that the existing code is working as expected. I have eMMC mounted on the board, which makes clock to always stay ON on SDH3.
Quoted 7 lines
So there is an OR gate implemented inside which takes input from
SDHx_AXI_ENand feeds back to all SDHx instances. Don't ask me why it has been designed that way :)And I did some experiment as well, so what I have observed is,
SDH_AXI_CLOCKis required to generate card detection, without that I do not see card detection working.
What that means is that if DT configures the interface to use its internal card detection, the AXI clock must never shut off when entering runtime-PM.
Yes, it means you don't get the same savings as you would by turning off that clock, but that's the choice between using the internal card detection and a GPIO for this. The code shouldn't force you to use a GPIO just because the Linux driver implementation dumbly disables the AXI clock.
Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net.
Quoted 35 lines · Russell King - ARM Linux
Quoted 22 lines · Vaibhav Hiremath
Came across below lines in the datasheet,
========= Copy-n-paste from datasheet============
All SDH interfaces share the same clock which is enabled when any of the SDH clock enables are
set (fromPMUA_SDH1_CLK_RES_CTRL,PMUA_SDH2_CLK_RES_CTRL,PMUA_SDH3_CLK_RES_CTRL,PMUA_SDH4_CLK_RES_CTRL,PMUA_SDH5_CLK_RES_CTRL), with clock source select and divider ratio controlled byPMUA_SDH1_CLK_RES_CTRL.==================================================
And I can confirm that after disabling AXI interface clock for all the SDH modules (1-5) I see I get an abort.
This clearly explains/justifies/proves that the existing code is working as expected. I have eMMC mounted on the board, which makes clock to always stay ON on SDH3.
Quoted 7 lines
So there is an OR gate implemented inside which takes input from
SDHx_AXI_ENand feeds back to all SDHx instances. Don't ask me why it has been designed that way :)And I did some experiment as well, so what I have observed is,
SDH_AXI_CLOCKis required to generate card detection, without that I do not see card detection working.What that means is that if DT configures the interface to use its internal card detection, the AXI clock must never shut off when entering runtime-PM.
Quoted 5 lines
Yes, it means you don't get the same savings as you would by turning off that clock, but that's the choice between using the internal card detection and a GPIO for this. The code shouldn't force you to use a GPIO just because the Linux driver implementation dumbly disables the AXI clock.
Note that should also happen if a SDIO card is inserted, and the SDIO IRQ is enabled - so the SDIO card can signal an interrupt back to the host.
Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net.
Quoted 27 lines · Russell King - ARM Linux
Quoted 26 lines · Vaibhav Hiremath
Came across below lines in the datasheet,
========= Copy-n-paste from datasheet============
All SDH interfaces share the same clock which is enabled when any of the SDH clock enables are
set (fromPMUA_SDH1_CLK_RES_CTRL,PMUA_SDH2_CLK_RES_CTRL,PMUA_SDH3_CLK_RES_CTRL,PMUA_SDH4_CLK_RES_CTRL,PMUA_SDH5_CLK_RES_CTRL), with clock source select and divider ratio controlled byPMUA_SDH1_CLK_RES_CTRL.==================================================
And I can confirm that after disabling AXI interface clock for all the SDH modules (1-5) I see I get an abort.
This clearly explains/justifies/proves that the existing code is working as expected. I have eMMC mounted on the board, which makes clock to always stay ON on SDH3.
So there is an OR gate implemented inside which takes input from
SDHx_AXI_ENand feeds back to all SDHx instances. Don't ask me why it has been designed that way :)
Quoted 8 lines
Quoted 3 lines
And I did some experiment as well, so what I have observed is,
SDH_AXI_CLOCKis required to generate card detection, without that I do not see card detection working.What that means is that if DT configures the interface to use its internal card detection, the AXI clock must never shut off when entering runtime-PM.
Yes, exactly.
Its clock driver which is doing this.
static struct mmp_param_gate_clk apmu_gate_clks[] = {
/* The gate clocks has mux parent. */
{PXA1928_CLK_SDH0, "sdh0_clk", "sdh_div", CLK_SET_RATE_PARENT, PXA1928_CLK_SDH0 * 4, 0x1b, 0x1b, 0x0, 0, &sdh0_lock}, };
Here the mask and enable_val both are set to 0x1b, which means it shuts off both peripheral and AXI clock both.
Quoted 6 lines
Yes, it means you don't get the same savings as you would by turning off that clock, but that's the choice between using the internal card detection and a GPIO for this. The code shouldn't force you to use a GPIO just because the Linux driver implementation dumbly disables the AXI clock.
Exactly,
In my case, luckily I have eMMC on board, which keeps AXI clock ON all the time. Not sure why somebody would keep dependency like this, inspite having individual control for AXI clock.
Thanks,
Vaibhav
Quoted 40 lines · Vaibhav Hiremath
Quoted 27 lines · Russell King - ARM Linux
Quoted 26 lines · Vaibhav Hiremath
Came across below lines in the datasheet,
========= Copy-n-paste from datasheet============
All SDH interfaces share the same clock which is enabled when any of the SDH clock enables are
set (fromPMUA_SDH1_CLK_RES_CTRL,PMUA_SDH2_CLK_RES_CTRL,PMUA_SDH3_CLK_RES_CTRL,PMUA_SDH4_CLK_RES_CTRL,PMUA_SDH5_CLK_RES_CTRL), with clock source select and divider ratio controlled byPMUA_SDH1_CLK_RES_CTRL.==================================================
And I can confirm that after disabling AXI interface clock for all the SDH modules (1-5) I see I get an abort.
This clearly explains/justifies/proves that the existing code is working as expected. I have eMMC mounted on the board, which makes clock to always stay ON on SDH3.
So there is an OR gate implemented inside which takes input from
SDHx_AXI_ENand feeds back to all SDHx instances. Don't ask me why it has been designed that way :)Quoted 8 lines
Quoted 3 lines
And I did some experiment as well, so what I have observed is,
SDH_AXI_CLOCKis required to generate card detection, without that I do not see card detection working.What that means is that if DT configures the interface to use its internal card detection, the AXI clock must never shut off when entering runtime-PM.
Yes, exactly.
Its clock driver which is doing this.
Quoted 8 lines
static struct mmp_param_gate_clk apmu_gate_clks[] = { /* The gate clocks has mux parent. */ {PXA1928_CLK_SDH0, "sdh0_clk", "sdh_div", CLK_SET_RATE_PARENT,
PXA1928_CLK_SDH0* 4,0x1b,0x1b,0x0, 0,&sdh0_lock}, };Here the mask and
enable_valboth are set to0x1b, which means it shuts off both peripheral and AXI clock both.
*Sigh*.
So, rather than represent the hardware in DT by telling the SDHCI code that you have two independent clocks, you've chosen to do the brain dead thing, and combine the two clocks *which are logically different* to suit the Linux implementation, thereby leaking implementation details into DT, and creating a compatibility headache through doing so.
Stop doing this. Just stop it. It's broken, it's wrong, and it's down right idiotic.
DT should _always_ describe the bloody hardware, not the implementation.
I suggest that you have only one way to solve this on this platform.
1. Declare new clocks from your PXA clock driver which expose the AXI and peripheral clock separately.
2. Add code (if not already there) to the SDHCI crap-pile to claim and appropriately manage these two clocks, falling back to the existing but broken method with existing DT.
3. Change DT to provide the new clocks to SDHCI.
That's about the only way I can see to ensure that an old DT file would continue to work with a new kernel, given this fsckup.
Please. In future, be careful when describing stuff in DT. Don't take short cuts to suit the implementation. Always describe the hardware, don't describe the implementation. *Especially* when it comes to things like device resources.
It really doesn't matter if the driver doesn't cope with them - the important thing is that the DT always correctly describes the hardware.
Signature · 2 lines
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net.
Quoted 72 lines · Russell King - ARM Linux
Quoted 40 lines · Vaibhav Hiremath
Quoted 27 lines · Russell King - ARM Linux
Quoted 26 lines · Vaibhav Hiremath
Came across below lines in the datasheet,
========= Copy-n-paste from datasheet============
All SDH interfaces share the same clock which is enabled when any of the SDH clock enables are
set (fromPMUA_SDH1_CLK_RES_CTRL,PMUA_SDH2_CLK_RES_CTRL,PMUA_SDH3_CLK_RES_CTRL,PMUA_SDH4_CLK_RES_CTRL,PMUA_SDH5_CLK_RES_CTRL), with clock source select and divider ratio controlled byPMUA_SDH1_CLK_RES_CTRL.==================================================
And I can confirm that after disabling AXI interface clock for all the SDH modules (1-5) I see I get an abort.
This clearly explains/justifies/proves that the existing code is working as expected. I have eMMC mounted on the board, which makes clock to always stay ON on SDH3.
So there is an OR gate implemented inside which takes input from
SDHx_AXI_ENand feeds back to all SDHx instances. Don't ask me why it has been designed that way :)Quoted 8 lines
Quoted 3 lines
And I did some experiment as well, so what I have observed is,
SDH_AXI_CLOCKis required to generate card detection, without that I do not see card detection working.What that means is that if DT configures the interface to use its internal card detection, the AXI clock must never shut off when entering runtime-PM.
Yes, exactly.
Its clock driver which is doing this.Quoted 8 lines
static struct mmp_param_gate_clk apmu_gate_clks[] = { /* The gate clocks has mux parent. */ {PXA1928_CLK_SDH0, "sdh0_clk", "sdh_div", CLK_SET_RATE_PARENT,
PXA1928_CLK_SDH0* 4,0x1b,0x1b,0x0, 0,&sdh0_lock}, };Here the mask and
enable_valboth are set to0x1b, which means it shuts off both peripheral and AXI clock both.*Sigh*.
So, rather than represent the hardware in DT by telling the SDHCI code that you have two independent clocks, you've chosen to do the brain dead thing, and combine the two clocks *which are logically different* to suit the Linux implementation, thereby leaking implementation details into DT, and creating a compatibility headache through doing so.
Stop doing this. Just stop it. It's broken, it's wrong, and it's down right idiotic.
DT should _always_ describe the bloody hardware, not the implementation.
I suggest that you have only one way to solve this on this platform.
1. Declare new clocks from your PXA clock driver which expose the AXI and peripheral clock separately.
2. Add code (if not already there) to the SDHCI crap-pile to claim and appropriately manage these two clocks, falling back to the existing but broken method with existing DT.
3. Change DT to provide the new clocks to SDHCI.
Quoted 3 lines
That's about the only way I can see to ensure that an old DT file would continue to work with a new kernel, given this fsckup.
sdhci-pxav3 driver already handles both, in terms of 'core' and 'io' clock. And it does disable both the clocks in runtime_pm_suspend()
So I have to find a way not to disable AXI clock here.
And yes, both clocks should be defined separately.
Looping Rob here as well.
Rob please add if I am missing anything here.