diff options
-rw-r--r-- | arch/arm/mach-tegra/clock.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-tegra/clock.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/clk.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra2_clocks.c | 19 |
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 | */ | ||
398 | void 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 | ||
395 | static int __clk_lock_all_spinlocks(void) | 409 | static 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); | |||
155 | void tegra_clk_init_from_table(struct tegra_clk_init_table *table); | 155 | void tegra_clk_init_from_table(struct tegra_clk_init_table *table); |
156 | unsigned long clk_get_rate_locked(struct clk *c); | 156 | unsigned long clk_get_rate_locked(struct clk *c); |
157 | int clk_set_rate_locked(struct clk *c, unsigned long rate); | 157 | int clk_set_rate_locked(struct clk *c, unsigned long rate); |
158 | void 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); | |||
26 | void tegra_periph_reset_assert(struct clk *c); | 26 | void tegra_periph_reset_assert(struct clk *c); |
27 | 27 | ||
28 | unsigned long clk_get_rate_all_locked(struct clk *c); | 28 | unsigned long clk_get_rate_all_locked(struct clk *c); |
29 | void 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. */ | ||
1062 | void 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 */ |
1056 | static void tegra2_emc_clk_init(struct clk *c) | 1075 | static void tegra2_emc_clk_init(struct clk *c) |
1057 | { | 1076 | { |