summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorPavan Kunapuli <pkunapuli@nvidia.com>2011-01-26 11:14:53 -0800
committerDan Willemsen <dwillemsen@nvidia.com>2011-04-26 15:50:12 -0700
commitec680fb8442cc35236842b7c128eaec20572fb21 (patch)
treeefb9824b8750369f5597b60be3680a1fc00d60c8 /drivers/mmc
parent51bbe2081ef72298371407169a8d23ed3fc328ac (diff)
arm: tegra: sdhci: Do not disable sdmmc4 clock
Do not switch off sdmmc4 clock. Also, removed ddr mode temporarily from linux mmc driver. Programming tap_delays and internal clock. Original-Change-Id: I830bf5e94ccd47e154c5ef9909e8bff1ff7754c0 Reviewed-on: http://git-master/r/17070 Reviewed-by: Jonathan Mayo <jmayo@nvidia.com> Reviewed-by: Scott Williams <scwilliams@nvidia.com> Tested-by: Scott Williams <scwilliams@nvidia.com> Change-Id: Ic1cff8dd85229fe903206f1dc9a967d600ba88c1
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-tegra.c38
-rw-r--r--drivers/mmc/host/sdhci.c6
2 files changed, 39 insertions, 5 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 700f81fd18d5..abe31cf9ffb2 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -55,6 +55,7 @@ struct tegra_sdhci_host {
int clk_enabled;
bool card_always_on;
u32 sdhci_ints;
+ unsigned int tap_delay;
};
static irqreturn_t carddetect_irq(int irq, void *data)
@@ -78,6 +79,22 @@ static int tegra_sdhci_enable_dma(struct sdhci_host *host)
return 0;
}
+#if defined (CONFIG_ARCH_TEGRA_3x_SOC)
+static void tegra_sdhci_set_trimmer_values(struct sdhci_host *sdhci)
+{
+ u32 ctrl;
+ struct tegra_sdhci_host *host = sdhci_priv(sdhci);
+
+ BUG_ON(host->tap_delay > 0xFF);
+
+ ctrl = sdhci_readl(sdhci, SDHCI_VENDOR_CLOCK_CNTRL);
+ ctrl &= ~(0xFF << SDHCI_VENDOR_CLOCK_CNTRL_TAP_VAL_SHIFT);
+ ctrl |= (host->tap_delay << SDHCI_VENDOR_CLOCK_CNTRL_TAP_VAL_SHIFT);
+ ctrl |= SDHCI_VENDOR_CLOCK_CNTRL_INPUT_IO_CLOCK_INTERNAL;
+ sdhci_writel(sdhci, ctrl, SDMMC_VENDOR_MISC_CNTRL);
+}
+#endif
+
static void tegra_sdhci_configure_capabilities(struct sdhci_host *sdhci)
{
#if defined (CONFIG_ARCH_TEGRA_3x_SOC)
@@ -100,20 +117,29 @@ static void tegra_sdhci_configure_capabilities(struct sdhci_host *sdhci)
ctrl |= SDMMC_VENDOR_MISC_CNTRL_SDMMC_SPARE0_ENABLE_SDR50;
ctrl |= SDMMC_VENDOR_MISC_CNTRL_SDMMC_SPARE0_ENABLE_SD3_0_SUPPORT;
sdhci_writel(sdhci, ctrl, SDMMC_VENDOR_MISC_CNTRL);
+
+ tegra_sdhci_set_trimmer_values(sdhci);
#endif
}
static void tegra_sdhci_enable_clock(struct tegra_sdhci_host *host, int enable)
{
+ unsigned int val;
+
if (enable && !host->clk_enabled) {
clk_enable(host->clk);
- sdhci_writeb(host->sdhci, 1, SDHCI_VENDOR_CLOCK_CNTRL);
+ val = sdhci_readb(host->sdhci, SDHCI_VENDOR_CLOCK_CNTRL);
+ val |= 1;
+ sdhci_writeb(host->sdhci, val, SDHCI_VENDOR_CLOCK_CNTRL);
host->clk_enabled = 1;
} else if (!enable && host->clk_enabled) {
- sdhci_writeb(host->sdhci, 0, SDHCI_VENDOR_CLOCK_CNTRL);
+ val = sdhci_readb(host->sdhci, SDHCI_VENDOR_CLOCK_CNTRL);
+ val &= ~(0x1);
+ sdhci_writeb(host->sdhci, val, SDHCI_VENDOR_CLOCK_CNTRL);
clk_disable(host->clk);
host->clk_enabled = 0;
}
+ host->sdhci->max_clk = clk_get_rate(host->clk);
}
static void tegra_sdhci_set_clock(struct sdhci_host *sdhci, unsigned int clock)
@@ -140,6 +166,8 @@ static int __devinit tegra_sdhci_probe(struct platform_device *pdev)
struct resource *res;
int irq;
void __iomem *ioaddr;
+ void __iomem *ioaddr_clk_rst;
+ unsigned int val = 0;
plat = pdev->dev.platform_data;
if (plat == NULL)
@@ -157,6 +185,12 @@ static int __devinit tegra_sdhci_probe(struct platform_device *pdev)
ioaddr = ioremap(res->start, res->end - res->start);
+ /* Fix ME: Enable the LVL2 CLK OVR bit */
+ ioaddr_clk_rst = ioremap(0x60006300, 0x400);
+ val = readl(ioaddr_clk_rst + 0xa0);
+ val |= 0x40;
+ writel(val, ioaddr_clk_rst + 0xa0);
+
sdhci = sdhci_alloc_host(&pdev->dev, sizeof(struct tegra_sdhci_host));
if (IS_ERR(sdhci)) {
rc = PTR_ERR(sdhci);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 4ea522ba5044..499a6fc73345 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -75,7 +75,7 @@ static void sdhci_dumpregs(struct sdhci_host *host)
sdhci_readl(host, SDHCI_INT_ENABLE),
sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
- sdhci_readw(host, SDHCI_ACMD12_ERR),
+ sdhci_readl(host, SDHCI_ACMD12_ERR),
sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
printk(KERN_DEBUG DRIVER_NAME ": Caps: 0x%08x | Max curr: 0x%08x\n",
sdhci_readl(host, SDHCI_CAPABILITIES),
@@ -2090,8 +2090,8 @@ int sdhci_add_host(struct sdhci_host *host)
* DDR mode support
*/
caps = sdhci_readb(host, SDHCI_HIGHER_CAPABILITIES);
- if (caps & SDHCI_CAN_SUPPORT_DDR50)
- mmc->caps |= MMC_CAP_DDR50;
+/* if (caps & SDHCI_CAN_SUPPORT_DDR50)
+ mmc->caps |= MMC_CAP_DDR50;*/
if (caps & SDHCI_CAN_SUPPORT_SDR50)
mmc->caps |= MMC_CAP_SDR50;
if (caps & SDHCI_CAN_SUPPORT_SDR104)