@@ -25,6 +25,7 @@
#include <linux/io.h>
#include <linux/err.h>
#include <plat/sdhci.h>
+#include <mach/cputype.h>
#include "sdhci.h"
#define DRIVER_NAME "sdhci-pxa"
@@ -46,10 +47,27 @@ struct sdhci_pxa {
* SDHCI core callbacks *
* *
\*****************************************************************************/
+#ifdef CONFIG_MMC_CLKGATE
+static void hardware_clk_gating (struct sdhci_host *host)
+{
+ unsigned short tmp;
+ int enable;
+
+ enable = host->mmc->clk_gated;
+ tmp = readw(host->ioaddr + SD_FIFO_PARAM);
+
+ if (enable)
+ tmp &= ~DIS_PAD_SD_CLK_GATE;
+ else
+ tmp |= DIS_PAD_SD_CLK_GATE;
+
+ writew(tmp, host->ioaddr + SD_FIFO_PARAM);
+}
+#endif
+
static void set_clock(struct sdhci_host *host, unsigned int clock)
{
struct sdhci_pxa *pxa = sdhci_priv(host);
- u32 tmp = 0;
if (clock == 0) {
if (pxa->clk_enable) {
@@ -58,11 +76,6 @@ static void set_clock(struct sdhci_host *host, unsigned int clock)
}
} else {
if (0 == pxa->clk_enable) {
- if (pxa->pdata->flags & PXA_FLAG_DISABLE_CLOCK_GATING) {
- tmp = readl(host->ioaddr + SD_FIFO_PARAM);
- tmp |= DIS_PAD_SD_CLK_GATE;
- writel(tmp, host->ioaddr + SD_FIFO_PARAM);
- }
clk_enable(pxa->clk);
pxa->clk_enable = 1;
}
@@ -71,6 +84,9 @@ static void set_clock(struct sdhci_host *host, unsigned int clock)
static struct sdhci_ops sdhci_pxa_ops = {
.set_clock = set_clock,
+#ifdef CONFIG_MMC_CLKGATE
+ .platform_hw_clk_gate = hardware_clk_gating,
+#endif
};
/*****************************************************************************\
@@ -145,6 +161,11 @@ static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+#ifdef CONFIG_MMC_CLKGATE
+ if (cpu_is_mmp2())
+ host->mmc->caps |= MMC_CAP_CLOCK_GATING_HW;
+#endif
+
ret = sdhci_add_host(host);
if (ret) {
dev_err(&pdev->dev, "failed to add host\n");