@@ -207,14 +207,15 @@ config MMC_SDHCI_PXAV3
If unsure, say N.
config MMC_SDHCI_PXAV2
- tristate "Marvell PXA9XX SD Host Controller support (PXAV2)"
+ tristate "Marvell PXA16X/PXA9XX SD Host Controller support (PXAV1/V2)"
depends on CLKDEV_LOOKUP
select MMC_SDHCI
select MMC_SDHCI_PLTFM
default y if CPU_PXA910
+ default y if CPU_PXA168
help
- This selects the Marvell(R) PXAV2 SD Host Controller.
- If you have a PXA9XX platform with SD Host Controller
+ This selects the Marvell(R) PXAV1/V2 SD Host Controller.
+ If you have a PXA16X or PXA9XX platform with SD Host Controller
and a card slot, say Y or M here.
If unsure, say N.
@@ -30,6 +30,7 @@
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/delay.h>
#include "sdhci.h"
#include "sdhci-pltfm.h"
@@ -75,7 +76,13 @@ static void pxav2_set_private_registers(struct sdhci_host *host, u8 mask)
writew(tmp, host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
}
- if (pdata && (pdata->flags & PXA_FLAG_ENABLE_CLOCK_GATING)) {
+ if (pdata && pdata->pxav1_controller) {
+ /* no clock gating */
+ tmp = readw(host->ioaddr + SD_FIFO_PARAM);
+ tmp |= DIS_PAD_SD_CLK_GATE;
+ writew(tmp, host->ioaddr + SD_FIFO_PARAM);
+ } else if (pdata && (pdata->flags
+ & PXA_FLAG_ENABLE_CLOCK_GATING)) {
tmp = readw(host->ioaddr + SD_FIFO_PARAM);
tmp &= ~CLK_GATE_SETTING_BITS;
writew(tmp, host->ioaddr + SD_FIFO_PARAM);
@@ -118,6 +125,20 @@ static u32 pxav2_get_max_clock(struct sdhci_host *host)
return clk_get_rate(pltfm_host->clk);
}
+/*
+ * we cannot talk to controller for 8 bus cycles according to sdio spec
+ * at lowest speed this is 100,000 HZ per cycle or 800,000 cycles
+ * which is quite a LONG TIME on a fast cpu -- so delay if needed
+ */
+static void platform_specific_completion(struct sdhci_host *host)
+{
+ struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
+ struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
+
+ if (host->clock < 3200000 && pdata && pdata->delay_in_ms)
+ mdelay(pdata->delay_in_ms);
+}
+
static struct sdhci_ops pxav2_sdhci_ops = {
.get_max_clock = pxav2_get_max_clock,
.platform_reset_exit = pxav2_set_private_registers,
@@ -218,6 +239,13 @@ static int sdhci_pxav2_probe(struct platform_device *pdev)
if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+ if (pdata->pxav1_controller) {
+ host->quirks |= SDHCI_QUIRK_NO_BUSY_IRQ
+ | SDHCI_QUIRK_32BIT_DMA_SIZE;
+ pxav2_sdhci_ops.platform_specific_completion
+ = platform_specific_completion;
+ }
+
if (pdata->quirks)
host->quirks |= pdata->quirks;
if (pdata->host_caps)
@@ -1001,6 +1001,9 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
mdelay(1);
}
+ if (host->ops->platform_specific_completion)
+ host->ops->platform_specific_completion(host);
+
mod_timer(&host->timer, jiffies + 10 * HZ);
host->cmd = cmd;
@@ -282,6 +282,7 @@ struct sdhci_ops {
void (*platform_resume)(struct sdhci_host *host);
void (*adma_workaround)(struct sdhci_host *host, u32 intmask);
void (*platform_init)(struct sdhci_host *host);
+ void (*platform_specific_completion)(struct sdhci_host *host);
};
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
@@ -54,6 +54,8 @@ struct sdhci_pxa_platdata {
unsigned int quirks;
unsigned int quirks2;
unsigned int pm_caps;
+ bool pxav1_controller; /* set if pxa168 */
+ unsigned int delay_in_ms;
};
struct sdhci_pxa {