summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavan Kunapuli <pkunapuli@nvidia.com>2012-06-27 17:51:54 +0530
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-07-19 00:55:57 -0700
commit42ed69a64a39d7cc84256bd3cb386f8dc8f09b84 (patch)
treedfed4bb8d4d29ce9f7af118e4be3f2c4664c8183
parent61c10696751004b4a6ceda1eb6acd247800a0eff (diff)
mmc: tegra: clean up interrupts logic in tuning
Disable the normal interrupts signalling before tuning and enable it only after the entire tuning process is done. Bug 860102 Signed-off-by: Pavan Kunapuli <pkunapuli@nvidia.com> Reviewed-on: http://git-master/r/111589 (cherry picked from commit 15a97f33f6cf1fc1c25441142f69f62ce5f7029b) Change-Id: I9eba9af65a50928dc4bb475e06cbf401963751bc Reviewed-on: http://git-master/r/116433 Reviewed-by: Rohan Somvanshi <rsomvanshi@nvidia.com> Tested-by: Rohan Somvanshi <rsomvanshi@nvidia.com>
-rw-r--r--drivers/mmc/host/sdhci-tegra.c41
1 files changed, 16 insertions, 25 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 9329cb57c548..86cee262b8fd 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -674,36 +674,15 @@ static void sdhci_tegra_set_tap_delay(struct sdhci_host *sdhci,
sdhci_writel(sdhci, vendor_ctrl, SDHCI_VENDOR_CLOCK_CNTRL);
}
-static void sdhci_tegra_clear_set_irqs(struct sdhci_host *host,
- u32 clear, u32 set)
-{
- u32 ier;
-
- ier = sdhci_readl(host, SDHCI_INT_ENABLE);
- ier &= ~clear;
- ier |= set;
- sdhci_writel(host, ier, SDHCI_INT_ENABLE);
- sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
-}
-
static int sdhci_tegra_run_frequency_tuning(struct sdhci_host *sdhci)
{
int err = 0;
u8 ctrl;
- u32 ier;
u32 mask;
unsigned int timeout = 10;
int flags;
u32 intstatus;
- /*
- * As per the Host Controller spec v3.00, tuning command
- * generates Buffer Read Ready interrupt only, so enable that.
- */
- ier = sdhci_readl(sdhci, SDHCI_INT_ENABLE);
- sdhci_tegra_clear_set_irqs(sdhci, ier, SDHCI_INT_DATA_AVAIL |
- SDHCI_INT_DATA_CRC);
-
mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT;
while (sdhci_readl(sdhci, SDHCI_PRESENT_STATE) & mask) {
if (timeout == 0) {
@@ -775,7 +754,6 @@ static int sdhci_tegra_run_frequency_tuning(struct sdhci_host *sdhci)
}
mdelay(1);
out:
- sdhci_tegra_clear_set_irqs(sdhci, SDHCI_INT_DATA_AVAIL, ier);
return err;
}
@@ -789,6 +767,7 @@ static int sdhci_tegra_execute_tuning(struct sdhci_host *sdhci)
unsigned int temp_pass_window = 0;
unsigned int best_low_pass_tap = 0;
unsigned int best_pass_window = 0;
+ u32 ier;
/* Tuning is valid only in SDR104 and SDR50 modes */
ctrl_2 = sdhci_readw(sdhci, SDHCI_HOST_CONTROL2);
@@ -801,11 +780,20 @@ static int sdhci_tegra_execute_tuning(struct sdhci_host *sdhci)
if (tap_delay_status == NULL) {
dev_err(mmc_dev(sdhci->mmc), "failed to allocate memory"
"for storing tap_delay_status\n");
- err = -ENOMEM;
- goto out;
+ return -ENOMEM;
}
/*
+ * Disable all interrupts signalling.Enable interrupt status
+ * detection for buffer read ready and data crc. We use
+ * polling for tuning as it involves less overhead.
+ */
+ ier = sdhci_readl(sdhci, SDHCI_INT_ENABLE);
+ sdhci_writel(sdhci, 0, SDHCI_SIGNAL_ENABLE);
+ sdhci_writel(sdhci, SDHCI_INT_DATA_AVAIL |
+ SDHCI_INT_DATA_CRC, SDHCI_INT_ENABLE);
+
+ /*
* Set each tap delay value and run frequency tuning. After each
* run, update the tap delay status as working or not working.
*/
@@ -856,7 +844,10 @@ static int sdhci_tegra_execute_tuning(struct sdhci_host *sdhci)
/* Run frequency tuning */
err = sdhci_tegra_run_frequency_tuning(sdhci);
-out:
+ /* Enable the normal interrupts signalling */
+ sdhci_writel(sdhci, ier, SDHCI_INT_ENABLE);
+ sdhci_writel(sdhci, ier, SDHCI_SIGNAL_ENABLE);
+
if (tap_delay_status)
kfree(tap_delay_status);