aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/clock.c14
-rw-r--r--arch/arm/mach-tegra/clock.h1
-rw-r--r--arch/arm/mach-tegra/include/mach/clk.h2
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c19
4 files changed, 36 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index f1f9c6d36bd2..165aa9c748f6 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -390,6 +390,20 @@ void __init tegra_init_clock(void)
390 tegra2_init_clocks(); 390 tegra2_init_clocks();
391} 391}
392 392
393/*
394 * The SDMMC controllers have extra bits in the clock source register that
395 * adjust the delay between the clock and data to compenstate for delays
396 * on the PCB.
397 */
398void tegra_sdmmc_tap_delay(struct clk *c, int delay)
399{
400 unsigned long flags;
401
402 spin_lock_irqsave(&c->spinlock, flags);
403 tegra2_sdmmc_tap_delay(c, delay);
404 spin_unlock_irqrestore(&c->spinlock, flags);
405}
406
393#ifdef CONFIG_DEBUG_FS 407#ifdef CONFIG_DEBUG_FS
394 408
395static int __clk_lock_all_spinlocks(void) 409static int __clk_lock_all_spinlocks(void)
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index ebe6ea8b0575..688316abc64e 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -155,5 +155,6 @@ int clk_reparent(struct clk *c, struct clk *parent);
155void tegra_clk_init_from_table(struct tegra_clk_init_table *table); 155void tegra_clk_init_from_table(struct tegra_clk_init_table *table);
156unsigned long clk_get_rate_locked(struct clk *c); 156unsigned long clk_get_rate_locked(struct clk *c);
157int clk_set_rate_locked(struct clk *c, unsigned long rate); 157int clk_set_rate_locked(struct clk *c, unsigned long rate);
158void tegra2_sdmmc_tap_delay(struct clk *c, int delay);
158 159
159#endif 160#endif
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h
index fa7f9ca1fdbd..c8baf8f80d23 100644
--- a/arch/arm/mach-tegra/include/mach/clk.h
+++ b/arch/arm/mach-tegra/include/mach/clk.h
@@ -26,4 +26,6 @@ void tegra_periph_reset_deassert(struct clk *c);
26void tegra_periph_reset_assert(struct clk *c); 26void tegra_periph_reset_assert(struct clk *c);
27 27
28unsigned long clk_get_rate_all_locked(struct clk *c); 28unsigned long clk_get_rate_all_locked(struct clk *c);
29void tegra_sdmmc_tap_delay(struct clk *c, int delay);
30
29#endif 31#endif
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index 7f7068714049..b85d2c75fb3c 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -74,6 +74,10 @@
74#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF 74#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF
75#define PERIPH_CLK_SOURCE_DIV_SHIFT 0 75#define PERIPH_CLK_SOURCE_DIV_SHIFT 0
76 76
77#define SDMMC_CLK_INT_FB_SEL (1 << 23)
78#define SDMMC_CLK_INT_FB_DLY_SHIFT 16
79#define SDMMC_CLK_INT_FB_DLY_MASK (0xF << SDMMC_CLK_INT_FB_DLY_SHIFT)
80
77#define PLL_BASE 0x0 81#define PLL_BASE 0x0
78#define PLL_BASE_BYPASS (1<<31) 82#define PLL_BASE_BYPASS (1<<31)
79#define PLL_BASE_ENABLE (1<<30) 83#define PLL_BASE_ENABLE (1<<30)
@@ -1052,6 +1056,21 @@ static struct clk_ops tegra_periph_clk_ops = {
1052 .reset = &tegra2_periph_clk_reset, 1056 .reset = &tegra2_periph_clk_reset,
1053}; 1057};
1054 1058
1059/* The SDMMC controllers have extra bits in the clock source register that
1060 * adjust the delay between the clock and data to compenstate for delays
1061 * on the PCB. */
1062void tegra2_sdmmc_tap_delay(struct clk *c, int delay)
1063{
1064 u32 reg;
1065
1066 delay = clamp(delay, 0, 15);
1067 reg = clk_readl(c->reg);
1068 reg &= ~SDMMC_CLK_INT_FB_DLY_MASK;
1069 reg |= SDMMC_CLK_INT_FB_SEL;
1070 reg |= delay << SDMMC_CLK_INT_FB_DLY_SHIFT;
1071 clk_writel(reg, c->reg);
1072}
1073
1055/* External memory controller clock ops */ 1074/* External memory controller clock ops */
1056static void tegra2_emc_clk_init(struct clk *c) 1075static void tegra2_emc_clk_init(struct clk *c)
1057{ 1076{