summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-05-28 00:21:30 -0700
committerNiket Sirsi <nsirsi@nvidia.com>2011-06-09 18:09:25 -0700
commita56136be2ba0c6408b559745252c90dd01885428 (patch)
tree7f4a0c6193bdad52e7f3f4dc8a63eee03766204a /arch
parent069e5fa2b4af5a95e511e4ef09819de4f07268e9 (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.c4
-rw-r--r--arch/arm/mach-tegra/board-enterprise.c16
-rw-r--r--arch/arm/mach-tegra/common.c16
-rw-r--r--arch/arm/mach-tegra/devices.c16
-rw-r--r--arch/arm/mach-tegra/include/mach/uncompress.h8
-rw-r--r--arch/arm/mach-tegra/tegra3_clocks.c93
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