diff options
author | Alex Frid <afrid@nvidia.com> | 2011-05-28 00:21:30 -0700 |
---|---|---|
committer | Niket Sirsi <nsirsi@nvidia.com> | 2011-06-09 18:09:25 -0700 |
commit | a56136be2ba0c6408b559745252c90dd01885428 (patch) | |
tree | 7f4a0c6193bdad52e7f3f4dc8a63eee03766204a /arch | |
parent | 069e5fa2b4af5a95e511e4ef09819de4f07268e9 (diff) |
ARM: tegra: clock: Change Tegra3 PLLP output frequency
On Tegra3 fixed PLLP output frequency has been set to 408MHz
(instead of 216MHz). Respectively changed:
- Tegra3 broads setting for UART, and audio clocks
- Tegra3 common clock setting for PLLP output dividers, SDMMC,
and system buses
- Tegra3 CPU backup configuration to guarantee safe backup at
any voltage
Bug 829081
Change-Id: Ied0c75204ccb2e4a428f0b8a124f0f3e053aa386
Reviewed-on: http://git-master/r/34813
Reviewed-by: Aleksandr Frid <afrid@nvidia.com>
Tested-by: Aleksandr Frid <afrid@nvidia.com>
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Reviewed-by: Scott Williams <scwilliams@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/board-cardhu.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-enterprise.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-tegra/common.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-tegra/devices.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/uncompress.h | 8 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_clocks.c | 93 |
6 files changed, 96 insertions, 57 deletions
diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c index dd865a06174d..d168c1742fe8 100644 --- a/arch/arm/mach-tegra/board-cardhu.c +++ b/arch/arm/mach-tegra/board-cardhu.c @@ -193,7 +193,7 @@ static __initdata struct tegra_clk_init_table cardhu_clk_init_table[] = { { "hda2codec_2x","pll_p", 48000000, false}, { "pwm", "clk_32k", 32768, false}, { "blink", "clk_32k", 32768, true}, - { "pll_a", NULL, 73728000, false}, + { "pll_a", NULL, 552960000, false}, { "pll_a_out0", NULL, 12288000, false}, { "d_audio", "pll_a_out0", 12288000, false}, { NULL, NULL, 0, 0}, @@ -467,7 +467,7 @@ static void __init cardhu_uart_init(void) pr_info("The debug console clock name is %s\n", debug_uart_clk->name); clk_enable(debug_uart_clk); - clk_set_rate(debug_uart_clk, 216000000); + clk_set_rate(debug_uart_clk, 408000000); } else { pr_err("Not getting the clock %s for debug console\n", debug_uart_clk->name); diff --git a/arch/arm/mach-tegra/board-enterprise.c b/arch/arm/mach-tegra/board-enterprise.c index 55d683e2cf50..43c7460c6c69 100644 --- a/arch/arm/mach-tegra/board-enterprise.c +++ b/arch/arm/mach-tegra/board-enterprise.c @@ -79,7 +79,7 @@ static struct plat_serial8250_port debug_uart_platform_data[] = { .type = PORT_TEGRA, .iotype = UPIO_MEM, .regshift = 2, - .uartclk = 216000000, + .uartclk = 408000000, }, { .flags = 0, } @@ -153,19 +153,19 @@ static inline void enterprise_bt_rfkill(void) { } static __initdata struct tegra_clk_init_table enterprise_clk_init_table[] = { /* name parent rate enabled */ - { "uarta", "pll_p", 216000000, true}, - { "uartb", "pll_p", 216000000, false}, - { "uartc", "pll_p", 216000000, false}, - { "uartd", "pll_p", 216000000, true}, - { "uarte", "pll_p", 216000000, false}, + { "uarta", "pll_p", 408000000, true}, + { "uartb", "pll_p", 408000000, false}, + { "uartc", "pll_p", 408000000, false}, + { "uartd", "pll_p", 408000000, true}, + { "uarte", "pll_p", 408000000, false}, { "pll_m", NULL, 0, true}, { "hda", "pll_p", 108000000, false}, { "hda2codec_2x","pll_p", 48000000, false}, { "pwm", "clk_32k", 32768, false}, { "blink", "clk_32k", 32768, true}, - { "pll_a", NULL, 56448000, false}, + { "pll_a", NULL, 564480000, false}, { "pll_a_out0", NULL, 11289600, false}, - { "d_audio","pll_a_out0", 11289600, false}, + { "d_audio", "pll_a_out0", 11289600, false}, { NULL, NULL, 0, 0}, }; diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index c378de84700d..d19a97977708 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c @@ -103,24 +103,28 @@ static __initdata struct tegra_clk_init_table common_clk_init_table[] = { /* set up clocks that should always be on */ /* name parent rate enabled */ { "clk_m", NULL, 0, true }, +#ifdef CONFIG_ARCH_TEGRA_2x_SOC { "pll_p", NULL, 216000000, true }, { "pll_p_out1", "pll_p", 28800000, true }, { "pll_p_out2", "pll_p", 48000000, true }, { "pll_p_out3", "pll_p", 72000000, true }, -#ifdef CONFIG_ARCH_TEGRA_2x_SOC { "pll_m", "clk_m", 600000000, true }, { "pll_m_out1", "pll_m", 120000000, true }, { "sclk", "pll_m_out1", 40000000, true }, { "hclk", "sclk", 40000000, true }, { "pclk", "hclk", 40000000, true }, #else + { "pll_p", NULL, 408000000, true }, + { "pll_p_out1", "pll_p", 9600000, true }, + { "pll_p_out2", "pll_p", 48000000, true }, + { "pll_p_out3", "pll_p", 102000000, true }, { "pll_m_out1", "pll_m", 275000000, true }, { "pll_c", NULL, ULONG_MAX, false }, { "pll_c_out1", "pll_c", 208000000, false }, - { "pll_p_out4", "pll_p", 108000000, true }, - { "sclk", "pll_p_out4", 108000000, true }, - { "hclk", "sclk", 108000000, true }, - { "pclk", "hclk", 54000000, true }, + { "pll_p_out4", "pll_p", 102000000, true }, + { "sclk", "pll_p_out4", 102000000, true }, + { "hclk", "sclk", 102000000, true }, + { "pclk", "hclk", 51000000, true }, #endif { "pll_x", NULL, 0, true }, { "cpu", NULL, 0, true }, @@ -132,7 +136,7 @@ static __initdata struct tegra_clk_init_table common_clk_init_table[] = { /* set frequencies of some device clocks */ { "pll_u", NULL, 480000000, false }, - { "sdmmc1", "pll_c", 48000000, false}, + { "sdmmc1", "pll_p", 48000000, false}, { "sdmmc3", "pll_p", 48000000, false}, { "sdmmc4", "pll_p", 48000000, false}, #ifndef CONFIG_ARCH_TEGRA_2x_SOC diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c index 46cae46954bd..53fe654e2ab3 100644 --- a/arch/arm/mach-tegra/devices.c +++ b/arch/arm/mach-tegra/devices.c @@ -31,6 +31,12 @@ #include <mach/iomap.h> #include <mach/dma.h> +#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) +#define UART_SOURCE_RATE 408000000 +#else +#define UART_SOURCE_RATE 216000000 +#endif + static struct resource i2c_resource1[] = { [0] = { .start = INT_I2C, @@ -1094,7 +1100,7 @@ static struct plat_serial8250_port debug_uarta_platform_data[] = { .type = PORT_TEGRA, .iotype = UPIO_MEM, .regshift = 2, - .uartclk = 216000000, + .uartclk = UART_SOURCE_RATE, }, { .flags = 0, @@ -1110,7 +1116,7 @@ static struct plat_serial8250_port debug_uartb_platform_data[] = { .type = PORT_TEGRA, .iotype = UPIO_MEM, .regshift = 2, - .uartclk = 216000000, + .uartclk = UART_SOURCE_RATE, }, { .flags = 0, @@ -1126,7 +1132,7 @@ static struct plat_serial8250_port debug_uartc_platform_data[] = { .type = PORT_TEGRA, .iotype = UPIO_MEM, .regshift = 2, - .uartclk = 216000000, + .uartclk = UART_SOURCE_RATE, }, { .flags = 0, @@ -1142,7 +1148,7 @@ static struct plat_serial8250_port debug_uartd_platform_data[] = { .type = PORT_TEGRA, .iotype = UPIO_MEM, .regshift = 2, - .uartclk = 216000000, + .uartclk = UART_SOURCE_RATE, }, { .flags = 0, @@ -1159,7 +1165,7 @@ static struct plat_serial8250_port debug_uarte_platform_data[] = { .type = PORT_TEGRA, .iotype = UPIO_MEM, .regshift = 2, - .uartclk = 216000000, + .uartclk = UART_SOURCE_RATE, }, { .flags = 0, diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h index 939dcd4d6b0a..9665858ab11d 100644 --- a/arch/arm/mach-tegra/include/mach/uncompress.h +++ b/arch/arm/mach-tegra/include/mach/uncompress.h @@ -66,6 +66,12 @@ #define DEBUG_UART_RST_CLR_BIT 0 #endif +#ifdef CONFIG_ARCH_TEGRA_2x_SOC +#define DEBUG_UART_DLL 0x75 +#else +#define DEBUG_UART_DLL 0xdd +#endif + static void putc(int c) { volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE; @@ -120,7 +126,7 @@ static inline void arch_decomp_setup(void) /* Set up debug UART. */ uart[UART_LCR << shift] |= UART_LCR_DLAB; - uart[UART_DLL << shift] = 0x75; + uart[UART_DLL << shift] = DEBUG_UART_DLL; uart[UART_DLM << shift] = 0x0; uart[UART_LCR << shift] = 3; } diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c index 48eb8c450361..b6ee72ac07b8 100644 --- a/arch/arm/mach-tegra/tegra3_clocks.c +++ b/arch/arm/mach-tegra/tegra3_clocks.c @@ -200,6 +200,8 @@ #define SUPER_CLK_DIVIDER 0x04 #define SUPER_CLOCK_DIV_U71_SHIFT 16 #define SUPER_CLOCK_DIV_U71_MASK (0xff << SUPER_CLOCK_DIV_U71_SHIFT) +/* guarantees safe cpu backup */ +#define SUPER_CLOCK_DIV_U71_MIN 0x2 #define BUS_CLK_DISABLE (1<<3) #define BUS_CLK_DIV_MASK 0x3 @@ -570,11 +572,13 @@ static void tegra3_super_clk_init(struct clk *c) c->parent = sel->input; if (c->flags & DIV_U71) { - val = clk_readl(c->reg + SUPER_CLK_DIVIDER); - val &= SUPER_CLOCK_DIV_U71_MASK; - clk_writel(val, c->reg + SUPER_CLK_DIVIDER); - c->div = (val >> SUPER_CLOCK_DIV_U71_SHIFT) + 2; + /* Init safe 7.1 divider value (does not affect PLLX path) */ + clk_writel(SUPER_CLOCK_DIV_U71_MIN << SUPER_CLOCK_DIV_U71_SHIFT, + c->reg + SUPER_CLK_DIVIDER); c->mul = 2; + c->div = 2; + if (!(c->parent->flags & PLLX)) + c->div += SUPER_CLOCK_DIV_U71_MIN; } else clk_writel(0, c->reg + SUPER_CLK_DIVIDER); @@ -618,6 +622,20 @@ static int tegra3_super_clk_set_parent(struct clk *c, struct clk *p) val &= ~(SUPER_SOURCE_MASK << shift); val |= (sel->value & SUPER_SOURCE_MASK) << shift; + /* 7.1 divider for CPU super-clock does not affect + PLLX path */ + if (c->flags & DIV_U71) { + u32 div = 0; + if (!(p->flags & PLLX)) { + div = clk_readl(c->reg + + SUPER_CLK_DIVIDER); + div &= SUPER_CLOCK_DIV_U71_MASK; + div >>= SUPER_CLOCK_DIV_U71_SHIFT; + } + c->div = div + 2; + c->mul = 2; + } + if (c->refcnt) clk_enable(p); @@ -647,6 +665,8 @@ static int tegra3_super_clk_set_rate(struct clk *c, unsigned long rate) if ((c->flags & DIV_U71) && (c->parent->flags & PLL_FIXED)) { int div = clk_div71_get_divider(c->parent->u.pll.fixed_rate, rate, c->flags, ROUND_DIVIDER_DOWN); + div = max(div, SUPER_CLOCK_DIV_U71_MIN); + clk_writel(div << SUPER_CLOCK_DIV_U71_SHIFT, c->reg + SUPER_CLK_DIVIDER); c->div = div + 2; @@ -691,7 +711,6 @@ static void tegra3_cpu_clk_disable(struct clk *c) static int tegra3_cpu_clk_set_rate(struct clk *c, unsigned long rate) { int ret; - unsigned long backup_rate; if (!c->dvfs || !c->dvfs->dvfs_rail) { #ifdef CONFIG_TEGRA_FPGA_PLATFORM @@ -722,12 +741,8 @@ static int tegra3_cpu_clk_set_rate(struct clk *c, unsigned long rate) goto out; } - backup_rate = clk_get_rate(c->u.cpu.backup); - if (c->u.cpu.backup->flags & PLL_FIXED) { - clk_set_rate(c->parent, rate); - if (rate <= backup_rate) - goto out; - } else if (rate == backup_rate) + ret = clk_set_rate(c->parent, rate); + if (!ret && (rate <= clk_get_rate(c->parent))) goto out; if (rate != clk_get_rate(c->u.cpu.main)) { @@ -1278,9 +1293,8 @@ static void tegra3_pll_clk_init(struct clk *c) return; } } - pr_warning("Clock %s has unknown fixed frequency\n", c->name); - c->mul = 1; - c->div = 1; + pr_err("Clock %s has unknown fixed frequency\n", c->name); + BUG(); } else if (val & PLL_BASE_BYPASS) { c->mul = 1; c->div = 1; @@ -1292,6 +1306,10 @@ static void tegra3_pll_clk_init(struct clk *c) else c->div *= (0x1 << ((val & PLL_BASE_DIVP_MASK) >> PLL_BASE_DIVP_SHIFT)); + if (c->flags & PLL_FIXED) { + unsigned long rate = clk_get_rate_locked(c); + BUG_ON(rate != c->u.pll.fixed_rate); + } } if (c->flags & PLLU) { @@ -1351,9 +1369,13 @@ static int tegra3_pll_clk_set_rate(struct clk *c, unsigned long rate) pr_debug("%s: %s %lu\n", __func__, c->name, rate); if (c->flags & PLL_FIXED) { - val = clk_readl(c->reg + PLL_BASE); - if (!(val & PLL_BASE_OVERRIDE) && (rate == c->u.pll.fixed_rate)) - return 0; + int ret = 0; + if (rate != c->u.pll.fixed_rate) { + pr_err("%s: Can not change %s fixed rate %lu to %lu\n", + __func__, c->name, c->u.pll.fixed_rate, rate); + ret = -EINVAL; + } + return ret; } p_div = 0; @@ -1423,10 +1445,6 @@ static int tegra3_pll_clk_set_rate(struct clk *c, unsigned long rate) c->div = sel->m * sel->p; old_base = val = clk_readl(c->reg + PLL_BASE); - if (c->flags & PLL_FIXED) { - BUG(); - val |= PLL_BASE_OVERRIDE; - } val &= ~(PLL_BASE_DIVM_MASK | PLL_BASE_DIVN_MASK | ((c->flags & PLLU) ? PLLU_BASE_POST_DIV : PLL_BASE_DIVP_MASK)); val |= (sel->m << PLL_BASE_DIVM_SHIFT) | @@ -2684,7 +2702,7 @@ static struct clk tegra_pll_p = { .vco_max = 1400000000, .freq_table = tegra_pll_p_freq_table, .lock_delay = 300, - .fixed_rate = 216000000, + .fixed_rate = 408000000, }, }; @@ -2729,6 +2747,10 @@ static struct clk tegra_pll_p_out4 = { }; static struct clk_pll_freq_table tegra_pll_a_freq_table[] = { + { 9600000, 564480000, 294, 5, 1, 4}, + { 9600000, 552960000, 288, 5, 1, 4}, + { 9600000, 24000000, 5, 2, 1, 1}, + { 28800000, 56448000, 49, 25, 1, 1}, { 28800000, 73728000, 64, 25, 1, 1}, { 28800000, 24000000, 5, 6, 1, 1}, @@ -2741,7 +2763,7 @@ static struct clk tegra_pll_a = { .ops = &tegra_pll_ops, .reg = 0xb0, .parent = &tegra_pll_p_out1, - .max_rate = 100000000, + .max_rate = 700000000, .u.pll = { .input_min = 2000000, .input_max = 31000000, @@ -3203,7 +3225,7 @@ static struct clk tegra_clk_sclk = { .reg = 0x28, .ops = &tegra_super_ops, .max_rate = 300000000, - .min_rate = 108000000, + .min_rate = 102000000, }; static struct clk tegra_clk_virtual_cpu_g = { @@ -3269,7 +3291,7 @@ static struct clk tegra_clk_pclk = { .reg_shift = 0, .ops = &tegra_bus_ops, .max_rate = 150000000, - .min_rate = 36000000, + .min_rate = 34000000, }; static struct clk tegra_clk_sbus_cmplx = { @@ -3281,7 +3303,7 @@ static struct clk tegra_clk_sbus_cmplx = { .hclk = &tegra_clk_hclk, .sclk_low = &tegra_pll_p_out4, .sclk_high = &tegra_pll_m_out1, - .threshold = 108000000, /* exact factor of low range pll_p */ + .threshold = 204000000, /* exact factor of low range pll_p */ }, }; @@ -3531,7 +3553,7 @@ struct clk tegra_list_clks[] = { PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */ PERIPH_CLK("dsia", "tegradc.0", "dsia", 48, 0, 500000000, mux_plld_out0, 0), PERIPH_CLK_EX("dsib", "tegradc.1", "dsib", 82, 0xd0, 500000000, mux_plld_out0_plld2_out0, MUX | PLLD, &tegra_dsib_clk_ops), - PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 72000000, mux_pllp_out3, 0), + PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 102000000, mux_pllp_out3, 0), PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */ PERIPH_CLK("csus", "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET), @@ -3713,14 +3735,14 @@ void __init tegra_soc_init_clocks(void) */ static struct cpufreq_frequency_table freq_table_300MHz[] = { - { 0, 216000 }, + { 0, 204000 }, { 1, 300000 }, { 2, CPUFREQ_TABLE_END }, }; static struct cpufreq_frequency_table freq_table_1p0GHz[] = { - { 0, 108000 }, - { 1, 216000 }, + { 0, 102000 }, + { 1, 204000 }, { 2, 312000 }, { 3, 456000 }, { 4, 608000 }, @@ -3732,8 +3754,8 @@ static struct cpufreq_frequency_table freq_table_1p0GHz[] = { }; static struct cpufreq_frequency_table freq_table_1p3GHz[] = { - { 0, 108000 }, - { 1, 216000 }, + { 0, 102000 }, + { 1, 204000 }, { 2, 340000 }, { 3, 480000 }, { 4, 640000 }, @@ -3747,8 +3769,8 @@ static struct cpufreq_frequency_table freq_table_1p3GHz[] = { }; static struct cpufreq_frequency_table freq_table_1p4GHz[] = { - { 0, 108000 }, - { 1, 216000 }, + { 0, 102000 }, + { 1, 204000 }, { 2, 370000 }, { 3, 480000 }, { 4, 620000 }, @@ -3973,6 +3995,7 @@ void tegra_clk_resume(void) tegra3_periph_clk_init(&tegra_clk_emc); tegra_emc_timing_invalidate(); - tegra3_pll_clk_init(&tegra_pll_u); + tegra3_pll_clk_init(&tegra_pll_u); /* Re-init utmi parameters */ + tegra3_pll_clk_init(&tegra_pll_p); /* Fire a bug if not restored */ } #endif |