sdhci: tegra: Set sdmmc controller clk rate
Pavan Kunapuli [Wed, 23 Nov 2011 11:15:58 +0000 (16:15 +0530)]
Setting the appropriate clk rates for sdmmc controllers. The min clk
rate is 50MHz. For freq between 50MHz and 104MHz, 104MHz clk rate is
set. If freq higher than 104MHz is requested, then the corresponding
clk rate is set.

Bug 906190
Bug 896706

Change-Id: Ie81c5b027e187503d420bbd571879a98c754d252
Signed-off-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Reviewed-on: http://git-master/r/64836
Reviewed-by: Lokesh Pathak <lpathak@nvidia.com>
Tested-by: Lokesh Pathak <lpathak@nvidia.com>

Rebase-Id: R3b9447946327071bba295453c391174953f02b1a

drivers/mmc/host/sdhci-tegra.c

index 6228b65..2818a05 100644 (file)
 
 #define SDHOST_1V8_OCR_MASK            0x8
 
+#define TEGRA_SDHOST_MIN_FREQ  50000000
+#define TEGRA2_SDHOST_STD_FREQ 50000000
+#define TEGRA3_SDHOST_STD_FREQ 104000000
+
+static unsigned int tegra_sdhost_min_freq;
+static unsigned int tegra_sdhost_std_freq;
 static void tegra_3x_sdhci_set_card_clock(struct sdhci_host *sdhci, unsigned int clock);
 static void tegra3_sdhci_post_reset_init(struct sdhci_host *sdhci);
 
@@ -348,7 +354,6 @@ set_clk:
 
        clk |= SDHCI_CLOCK_CARD_EN;
        sdhci_writew(sdhci, clk, SDHCI_CLOCK_CONTROL);
-
 out:
        sdhci->clock = clock;
 }
@@ -370,6 +375,13 @@ static void tegra_sdhci_set_clock(struct sdhci_host *sdhci, unsigned int clock)
                        sdhci_writeb(sdhci, ctrl, SDHCI_VENDOR_CLOCK_CNTRL);
                        tegra_host->clk_enabled = true;
                }
+               if (clock <= tegra_sdhost_min_freq)
+                       clk_set_rate(pltfm_host->clk, tegra_sdhost_min_freq);
+               else if (clock <= tegra_sdhost_std_freq)
+                       clk_set_rate(pltfm_host->clk, tegra_sdhost_std_freq);
+               else
+                       clk_set_rate(pltfm_host->clk, clock);
+               sdhci->max_clk = clk_get_rate(pltfm_host->clk);
                if (tegra_host->hw_ops->set_card_clock)
                        tegra_host->hw_ops->set_card_clock(sdhci, clock);
        } else if (!clock && tegra_host->clk_enabled) {
@@ -628,10 +640,13 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
        if (plat->mmc_data.embedded_sdio)
                host->mmc->pm_flags = MMC_PM_KEEP_POWER;
 
+       tegra_sdhost_min_freq = TEGRA_SDHOST_MIN_FREQ;
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
        tegra_host->hw_ops = &tegra_2x_sdhci_ops;
+       tegra_sdhost_std_freq = TEGRA2_SDHOST_STD_FREQ;
 #else
        tegra_host->hw_ops = &tegra_3x_sdhci_ops;
+       tegra_sdhost_std_freq = TEGRA3_SDHOST_STD_FREQ;
 #endif
 
        rc = sdhci_add_host(host);