The MMC core uses mmc->clk_disable to request that the card clock is
stopped, but the PL180 driver leaves SDI_CLKCR_CLKEN unchanged. This can
leave inactive hosts driving their card clocks.

Honor clk_disable when programming the clock control register. Also enable
the PL180 power-save mode so the clock stops automatically while the bus is
idle.

Signed-off-by: Linus Walleij <[email protected]>
---
 drivers/mmc/arm_pl180_mmci.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c
index af21b814641e..528612359789 100644
--- a/drivers/mmc/arm_pl180_mmci.c
+++ b/drivers/mmc/arm_pl180_mmci.c
@@ -294,6 +294,11 @@ static int  host_set_ios(struct mmc *dev)
        u32 sdi_clkcr;
 
        sdi_clkcr = readl(&host->base->clock);
+       sdi_clkcr |= SDI_CLKCR_PWRSAV;
+       if (dev->clk_disable)
+               sdi_clkcr &= ~SDI_CLKCR_CLKEN;
+       else
+               sdi_clkcr |= SDI_CLKCR_CLKEN;
 
        /* Ramp up the clock rate */
        if (dev->clock) {
@@ -400,7 +405,7 @@ static int arm_pl180_mmc_probe(struct udevice *dev)
 
        host->pwr_init = INIT_PWR;
        host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V1 | SDI_CLKCR_CLKEN |
-                           SDI_CLKCR_HWFC_EN;
+                           SDI_CLKCR_PWRSAV | SDI_CLKCR_HWFC_EN;
        host->clock_in = clk_get_rate(&clk);
 
        cfg->name = dev->name;
@@ -418,7 +423,7 @@ static int arm_pl180_mmc_probe(struct udevice *dev)
        case UX500V2_MMCI_ID:
                host->pwr_init = SDI_PWR_OPD | SDI_PWR_PWRCTRL_ON;
                host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V2 | SDI_CLKCR_CLKEN |
-                                   SDI_CLKCR_HWFC_EN;
+                                   SDI_CLKCR_PWRSAV | SDI_CLKCR_HWFC_EN;
                cfg->voltages = VOLTAGE_WINDOW_MMC;
                cfg->f_min = host->clock_in / (2 + SDI_CLKCR_CLKDIV_INIT_V2);
                host->version2 = true;

-- 
2.55.0

Reply via email to