summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-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
4 files changed, 86 insertions, 47 deletions
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 951a4cc3a061..fbbdb7ccd960 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -109,32 +109,36 @@ void tegra_assert_system_reset(char mode, const char *cmd)
static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
/* 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 },
{ "pll_p_out4", "pll_p", 108000000, 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
{ "csite", NULL, 0, true },
{ "emc", NULL, 0, true },
{ "cpu", NULL, 0, true },
{ "kfuse", NULL, 0, true },
{ "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 1142a402b60d..39523ae61206 100644
--- a/arch/arm/mach-tegra/devices.c
+++ b/arch/arm/mach-tegra/devices.c
@@ -33,6 +33,12 @@
#include <mach/usb_phy.h>
#include "gpio-names.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,
@@ -723,7 +729,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,
@@ -739,7 +745,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,
@@ -755,7 +761,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,
@@ -771,7 +777,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,
@@ -788,7 +794,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 68e400e01a91..99853ff4f76a 100644
--- a/arch/arm/mach-tegra/tegra3_clocks.c
+++ b/arch/arm/mach-tegra/tegra3_clocks.c
@@ -198,6 +198,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
@@ -568,11 +570,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);
@@ -616,6 +620,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);
@@ -645,6 +663,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;
@@ -689,7 +709,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
@@ -720,12 +739,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)) {
@@ -1276,9 +1291,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;
@@ -1290,6 +1304,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) {
@@ -1349,9 +1367,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;
@@ -1421,10 +1443,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) |
@@ -2682,7 +2700,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,
},
};
@@ -2727,6 +2745,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},
@@ -2739,7 +2761,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,
@@ -3201,7 +3223,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 = {
@@ -3276,7 +3298,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 = {
@@ -3288,7 +3310,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 */
},
};
@@ -3538,7 +3560,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),
@@ -3722,14 +3744,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 },
@@ -3741,8 +3763,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 },
@@ -3756,8 +3778,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 },
@@ -3982,6 +4004,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